363 lines
14 KiB
JavaScript
363 lines
14 KiB
JavaScript
import React, { Component } from 'react'
|
||
import { Form, Input, InputNumber, Radio, Select, Spin, Switch, TreeSelect } from 'antd'
|
||
import { AntIcon, IconSelector } from 'components'
|
||
import { cloneDeep } from 'lodash'
|
||
import getDictData from 'util/dic'
|
||
import { api } from 'common/api'
|
||
import { EMPTY_ID } from 'util/global'
|
||
|
||
const initialValues = {
|
||
type: '1',
|
||
openType: '1',
|
||
visible: true,
|
||
sort: 100
|
||
}
|
||
|
||
export default class form extends Component {
|
||
|
||
state = {
|
||
// 加载状态
|
||
loading: true,
|
||
codes: {
|
||
menuType: [],
|
||
openType: []
|
||
},
|
||
options: {
|
||
appList: [],
|
||
parentTreeData: []
|
||
},
|
||
|
||
type: initialValues.type,
|
||
openType: initialValues.openType,
|
||
icon: ''
|
||
}
|
||
|
||
// 表单实例
|
||
form = React.createRef()
|
||
|
||
iconSelector = React.createRef()
|
||
|
||
// 初始化数据
|
||
record = {}
|
||
|
||
/**
|
||
* mount后回调
|
||
*/
|
||
componentDidMount() {
|
||
this.props.created && this.props.created(this)
|
||
}
|
||
|
||
/**
|
||
* 填充数据
|
||
* 可以在设置this.record之后对其作出数据结构调整
|
||
* [异步,必要]
|
||
* @param {*} params
|
||
*/
|
||
async fillData(params) {
|
||
this.record = cloneDeep(params.record)
|
||
//#region 从后端转换成前段所需格式
|
||
const { menuType, openType } = await getDictData('menu_type', 'open_type')
|
||
const appList = await this.onLoadSysApplist()
|
||
let parentTreeData = []
|
||
if (params.isParent) {
|
||
parentTreeData = await this.onLoadMenuTree(params.parent.application)
|
||
} else if (params.record) {
|
||
parentTreeData = await this.onLoadMenuTree(params.record.application)
|
||
}
|
||
const icon = params.record && params.record.icon
|
||
this.setState({
|
||
codes: {
|
||
menuType,
|
||
openType
|
||
},
|
||
options: {
|
||
appList,
|
||
parentTreeData
|
||
},
|
||
icon
|
||
})
|
||
//#endregion
|
||
const form = this.form.current
|
||
if (params.isParent) {
|
||
form.setFieldsValue({
|
||
pid: params.parent.id,
|
||
application: params.parent.application
|
||
})
|
||
} else {
|
||
form.setFieldsValue(this.record)
|
||
}
|
||
|
||
this.setState({
|
||
loading: false
|
||
})
|
||
|
||
this.onTypeChange()
|
||
}
|
||
|
||
/**
|
||
* 获取数据
|
||
* 可以对postData进行数据结构调整
|
||
* [异步,必要]
|
||
* @returns
|
||
*/
|
||
async getData() {
|
||
const form = this.form.current
|
||
|
||
const valid = await form.validateFields()
|
||
if (valid) {
|
||
const postData = form.getFieldsValue()
|
||
if (this.record) {
|
||
postData.id = this.record.id
|
||
}
|
||
//#region 从前段转换后端所需格式
|
||
//#endregion
|
||
return postData
|
||
}
|
||
}
|
||
|
||
//#region 自定义方法
|
||
async onLoadSysApplist() {
|
||
const { data } = await api.getAppList()
|
||
return data
|
||
}
|
||
|
||
async onLoadMenuTree(application) {
|
||
const { data } = await api.getMenuTree({ application })
|
||
return [{
|
||
id: EMPTY_ID,
|
||
parentId: undefined,
|
||
title: '顶级',
|
||
value: EMPTY_ID,
|
||
pid: undefined,
|
||
children: data,
|
||
}]
|
||
}
|
||
|
||
|
||
onTypeChange() {
|
||
this.onTypeChangeGroup()
|
||
const form = this.form.current
|
||
const { type } = form.getFieldsValue()
|
||
if (['0', '2'].includes(type)) {
|
||
form.setFieldsValue({
|
||
openType: '0'
|
||
})
|
||
} else {
|
||
form.setFieldsValue({
|
||
openType: '1'
|
||
})
|
||
}
|
||
}
|
||
|
||
onOpenTypeChange() {
|
||
this.onTypeChangeGroup()
|
||
}
|
||
|
||
onTypeChangeGroup() {
|
||
const form = this.form.current
|
||
const { type, openType } = form.getFieldsValue()
|
||
// if (type == 1 && openType == 2) {
|
||
// form.setFieldsValue({
|
||
// component: 'iframe'
|
||
// })
|
||
// } else {
|
||
// form.setFieldsValue({
|
||
// component: ''
|
||
// })
|
||
// }
|
||
|
||
this.setState({
|
||
type,
|
||
openType
|
||
})
|
||
}
|
||
|
||
async onApplicationChange(value) {
|
||
this.setState({
|
||
loading: true
|
||
})
|
||
const parentTreeData = await this.onLoadMenuTree(value)
|
||
this.setState({
|
||
loading: false,
|
||
options: {
|
||
...this.state.options,
|
||
parentTreeData
|
||
}
|
||
})
|
||
this.form.current.setFieldsValue({
|
||
pid: undefined
|
||
})
|
||
}
|
||
|
||
onSelectIcon(icon) {
|
||
this.form.current.setFieldsValue({
|
||
icon
|
||
})
|
||
this.setState({ icon })
|
||
}
|
||
//#endregion
|
||
|
||
render() {
|
||
return (
|
||
<Form
|
||
initialValues={initialValues}
|
||
ref={this.form}
|
||
className="yo-form"
|
||
>
|
||
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
|
||
<div className="yo-form-group">
|
||
<h3 className="h3">基本信息</h3>
|
||
<div className="yo-form-group">
|
||
<Form.Item
|
||
label="菜单类型"
|
||
name="type"
|
||
help={
|
||
<>
|
||
目录:默认添加在顶级
|
||
<br />菜单:
|
||
<br />按钮:
|
||
</>
|
||
}
|
||
rules={[{ required: true, message: '请选择菜单类型' }]}
|
||
>
|
||
<Radio.Group onChange={(e) => this.onTypeChange(e)}>
|
||
{
|
||
this.state.codes.menuType.map(item => {
|
||
return (
|
||
<Radio.Button
|
||
key={item.code}
|
||
value={item.code}
|
||
>{item.value}</Radio.Button>
|
||
)
|
||
})
|
||
}
|
||
</Radio.Group>
|
||
</Form.Item>
|
||
<Form.Item label="名称" name="name" rules={[{ required: true, message: '请输入名称' }]}>
|
||
<Input autoComplete="off" placeholder="请输入名称" />
|
||
</Form.Item>
|
||
<Form.Item label="唯一编码" name="code">
|
||
<Input autoComplete="off" placeholder="请输入唯一编码" />
|
||
</Form.Item>
|
||
<Form.Item label="所属应用" name="application" rules={[{ required: true, message: '请选择所属应用' }]}>
|
||
<Select placeholder="请选择所属应用" onChange={(value) => this.onApplicationChange(value)}>
|
||
{
|
||
this.state.options.appList.map(item => {
|
||
return (
|
||
<Select.Option
|
||
key={item.code}
|
||
value={item.code}
|
||
>{item.name}</Select.Option>
|
||
)
|
||
})
|
||
}
|
||
</Select>
|
||
</Form.Item>
|
||
{
|
||
this.state.type != 0 &&
|
||
<Form.Item label="父级菜单" name="pid" rules={[{ required: true, message: '请选择父级' }]}>
|
||
<TreeSelect
|
||
dropdownStyle={{ maxHeight: '300px', overflow: 'auto' }}
|
||
treeData={this.state.options.parentTreeData}
|
||
placeholder="请选择父级菜单"
|
||
/>
|
||
</Form.Item>
|
||
}
|
||
</div>
|
||
<h3 className="h3">扩展信息</h3>
|
||
<div className="yo-form-group">
|
||
{
|
||
this.state.type == 1 &&
|
||
<Form.Item label="打开方式" name="openType">
|
||
<Radio.Group onChange={(e) => this.onOpenTypeChange(e)}>
|
||
{
|
||
this.state.codes.openType.map(item => {
|
||
return (
|
||
<Radio.Button
|
||
key={item.code}
|
||
value={item.code}
|
||
>{item.value}</Radio.Button>
|
||
)
|
||
})
|
||
}
|
||
</Radio.Group>
|
||
</Form.Item>
|
||
}
|
||
{
|
||
this.state.type == 1 && this.state.openType == 1 &&
|
||
<Form.Item label="前端组件" name="component" rules={[{ required: true, message: '请输入前端组件' }]}>
|
||
<Input autoComplete="off" placeholder="请输入前端组件" />
|
||
</Form.Item>
|
||
}
|
||
{
|
||
this.state.type == 1 && this.state.openType == 2 &&
|
||
<Form.Item label="内链地址" name="router" rules={[{ required: true, message: '请输入内链地址' }]}>
|
||
<Input autoComplete="off" placeholder="请输入内链地址" />
|
||
</Form.Item>
|
||
}
|
||
{
|
||
this.state.type == 1 && this.state.openType == 3 &&
|
||
<Form.Item label="外链地址" name="link" rules={[{ required: true, message: '请输入外链地址' }]}>
|
||
<Input autoComplete="off" placeholder="请输入外链地址" />
|
||
</Form.Item>
|
||
}
|
||
{
|
||
this.state.type == 2 &&
|
||
<Form.Item label="权限标识" name="permission" rules={[{ required: true, message: '请输入权限标识' }]}>
|
||
<Input autoComplete="off" placeholder="请输入权限标识" />
|
||
</Form.Item>
|
||
}
|
||
{
|
||
this.state.type == 2 &&
|
||
<Form.Item label="关联上级菜单显示" name="visibleParent" valuePropName="checked">
|
||
<Switch />
|
||
</Form.Item>
|
||
}
|
||
<Form.Item label="可见性" name="visible" valuePropName="checked">
|
||
<Switch />
|
||
</Form.Item>
|
||
{
|
||
this.state.type != 2 &&
|
||
<Form.Item label="图标" name="icon">
|
||
<Input
|
||
disabled
|
||
placeholder="请选择图标"
|
||
addonBefore={
|
||
this.state.icon &&
|
||
<AntIcon type={this.state.icon} />
|
||
}
|
||
addonAfter={
|
||
<AntIcon
|
||
type="setting"
|
||
onClick={() =>
|
||
this
|
||
.iconSelector
|
||
.current
|
||
.open(this.form.current.getFieldValue('icon'))
|
||
}
|
||
/>
|
||
}
|
||
/>
|
||
</Form.Item>
|
||
}
|
||
<Form.Item label="排序" name="sort">
|
||
<InputNumber
|
||
max={1000}
|
||
min={0}
|
||
className="w-100-p"
|
||
placeholder="请输入排序"
|
||
/>
|
||
</Form.Item>
|
||
<Form.Item label="备注信息" name="remark">
|
||
<Input.TextArea placeholder="请输入备注信息" />
|
||
</Form.Item>
|
||
</div>
|
||
</div>
|
||
</Spin>
|
||
|
||
<IconSelector ref={this.iconSelector} onSelect={(icon) => this.onSelectIcon(icon)} />
|
||
</Form>
|
||
)
|
||
}
|
||
}
|