king
2021-05-26 f66e19dd13af07ee466306632ad43c72f1f16ae7
src/menu/components/card/cardcomponent/settingform/index.jsx
@@ -1,163 +1,59 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, Icon, Radio, Tooltip, InputNumber, notification } from 'antd'
import { Form, Row, Col, Radio, Tooltip, Icon, Input, InputNumber, Select, Cascader } from 'antd'
import { formRule } from '@/utils/option.js'
import FileUpload from '@/tabviews/zshare/fileupload'
import ColorSketch from '@/mob/colorsketch'
import './index.scss'
const cardTypeOptions = {
  text: ['eleType', 'datatype', 'value', 'format', 'fontSize', 'fontWeight', 'width', 'height', 'color', 'align', 'padding', 'prefix', 'postfix'],
  number: ['eleType', 'datatype', 'value', 'format', 'fontSize', 'fontWeight', 'width', 'height', 'color', 'align', 'padding', 'prefix', 'postfix'],
  picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'radius', 'padding', 'url'],
  icon: ['eleType', 'icon', 'fontSize', 'width', 'height', 'color', 'align', 'padding', 'tooltip'],
  link: ['eleType', 'datatype', 'value', 'labelfield', 'fontSize', 'width', 'height', 'color', 'align', 'padding', 'prefix'],
  slider: ['eleType', 'field', 'width', 'color', 'padding', 'maxValue'],
  splitline: ['eleType', 'color', 'width', 'padding'],
}
const { TextArea } = Input
class MainSearch extends Component {
class SettingForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,      // 字典项
    config: PropTypes.object,    // 组件信息
    formlist: PropTypes.any,     // 表单信息
    card: PropTypes.any,         // 按钮信息
    inputSubmit: PropTypes.any   // 回车提交事件
    cards: PropTypes.object,     // 卡片集
    setting: PropTypes.object,   // 数据源配置
    inputSubmit: PropTypes.func  // 回车事件
  }
  state = {
    formlist: null,  // 表单信息
    eleType: '',
    datatype: ''
    type: this.props.setting.type || 'simple',
    click: this.props.setting.click || '',
    appType: sessionStorage.getItem('appType'),
    menulist: []
  }
  UNSAFE_componentWillMount () {
    const { card, config } = this.props
  UNSAFE_componentWillMount() {
    const { appType } = this.state
    let menulist = null
    let _options = this.getOptions(card.eleType, card.datatype)
    if (appType) {
      menulist = sessionStorage.getItem('appMenus')
    } else {
      menulist = sessionStorage.getItem('fstMenuList')
    }
    this.setState({
      eleType: card.eleType,
      datatype: card.datatype,
      formlist: this.props.formlist.map(item => {
        item.hidden = !_options.includes(item.key)
    if (menulist) {
      try {
        menulist = JSON.parse(menulist)
      } catch {
        menulist = []
      }
    } else {
      menulist = []
    }
    this.setState({menulist})
  }
        if (item.key === 'field') {
          item.options = []
          config.columns.forEach(col => {
            if (!/^Nvarchar/ig.test(col.datatype) && (card.eleType === 'number' || card.eleType === 'slider')) {
              item.options.push({
                value: col.field,
                text: col.label
              })
            } else if (/^Nvarchar/ig.test(col.datatype) && card.eleType !== 'number' && card.eleType !== 'slider') {
              item.options.push({
                value: col.field,
                text: col.label
              })
            }
          })
        } else if (item.key === 'labelfield') {
          item.options = []
          config.columns.forEach(col => {
            if (/^Nvarchar/ig.test(col.datatype)) {
              item.options.push({
                value: col.field,
                text: col.label
              })
            }
          })
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          resolve(values)
        } else {
          reject(err)
        }
        return item
      })
    })
  }
  getOptions = (eleType, datatype) => {
    let _options = fromJS(cardTypeOptions[eleType]).toJS() // 选项列表
    if (['text', 'number', 'picture', 'link'].includes(eleType)) {
      if (datatype === 'dynamic') {
        _options.push('field')
      }
    }
    return _options
  }
  /**
   * @description 下拉切换
   * 1、打开方式切换,重置可见表单和表单值
   * 2、显示位置切换,重置选择行
   * 3、切换标签类型,重置可选标签
   */
  selectChange = (key, value, option) => {
    const { config } = this.props
    const { datatype } = this.state
    if (key === 'eleType') {
      let _options = this.getOptions(value, datatype)
      let _formlist = this.state.formlist.map(item => {
        item.hidden = !_options.includes(item.key)
        if (item.key === 'field') {
          item.options = []
          config.columns.forEach(col => {
            if (!/^Nvarchar/ig.test(col.datatype) && (value === 'number' || value === 'slider')) {
              item.options.push({
                value: col.field,
                text: col.label
              })
            } else if (/^Nvarchar/ig.test(col.datatype) && value !== 'number' && value !== 'slider') {
              item.options.push({
                value: col.field,
                text: col.label
              })
            }
          })
        }
        return item
      })
      this.setState({
        eleType: value,
        formlist: _formlist
      }, () => {
        if (value === 'slider') {
          this.props.form.setFieldsValue({width: 24, color: '#1890ff'})
        } else if (value === 'splitline') {
          this.props.form.setFieldsValue({width: 24, color: '#e8e8e8'})
        }
      })
    } else if (key === 'field') {
      if (this.props.form.getFieldValue('value') !== undefined) {
        this.props.form.setFieldsValue({value: option.props.title})
      }
    }
  }
  onChange = (e, key) => {
    const { eleType } = this.state
    let value = e.target.value
    if (key === 'datatype') {
      let _options = this.getOptions(eleType, value)
      this.setState({
        datatype: value,
        formlist: this.state.formlist.map(item => {
          item.hidden = !_options.includes(item.key)
          return item
        })
      })
    }
  }
  handleSubmit = (e) => {
@@ -168,237 +64,194 @@
    }
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.state.formlist.forEach((item, index) => {
      if (item.hidden) return
      if (item.type === 'text') { // 文本搜索
        let rules = []
        if (item.key === 'padding') {
          rules = [{
            pattern: /^\d+px$|^\d+px\s\d+px$|^\d+px\s\d+px\s\d+px$|^\d+px\s\d+px\s\d+px\s\d+px$/ig,
            message: '请正确输入内边距!'
          }]
        }
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  },
                  {
                    max: formRule.input.max,
                    message: formRule.input.message
                  },
                  ...rules
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: item.readonly ? false : !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<InputNumber min={item.min || 0} max={item.max || 10000} precision={item.precision || 0} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉搜索
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value, option) => {this.selectChange(item.key, value, option)}}
                  getPopupContainer={() => document.getElementById('card-winter')}
                >
                  {item.options.map((option, index) =>
                    <Select.Option id={`${index}`} title={option.text} key={`${index}`} value={option.value}>
                      {item.key === 'icon' && option.value && <Icon type={option.value} />} {option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'radio') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Radio.Group onChange={(e) => {this.onChange(e, item.key)}} disabled={item.readonly}>
                  {
                    item.options.map(option => {
                      return (
                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
                      )
                    })
                  }
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'color') {
        fields.push(
          <Col span={12} key={index} className="color-form">
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <ColorSketch />
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'file') {
        let filelist = []
        if (item.initVal) {
          filelist = [{
            uid: `1`,
            name: item.initVal.slice(item.initVal.lastIndexOf('/') + 1),
            status: 'done',
            url: item.initVal,
            origin: true
          }]
        }
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: filelist,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <FileUpload maxFile={item.maxfile} fileType={'text'} />
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.uuid = this.props.card.uuid
          values.marks = this.props.card.marks || null
          if (values.url) {
            if (values.url.length > 0) {
              if (values.url[0].origin && values.url[0].url) {
                values.url = values.url[0].url
              } else if (!values.url[0].origin && values.url[0].status === 'done' && values.url[0].response) {
                values.url = values.url[0].response
              } else {
                values.url = ''
              }
            } else {
              values.url = ''
            }
          }
          if (values.eleType === 'picture' && values.datatype === 'static' && !values.url) {
            notification.warning({
              top: 92,
              message: '尚未添加图片或图片上传失败,请重新添加!',
              duration: 5
            })
            return
          }
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const { setting, cards } = this.props
    const { getFieldDecorator } = this.props.form
    const { menulist, click, appType } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 7 }
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 17 }
        sm: { span: 16 }
      }
    }
    return (
      <Form {...formItemLayout} className="menu-card-detail-form" id="card-winter">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
      <div className="model-menu-card-setting-form">
        <Form {...formItemLayout}>
          <Row gutter={24}>
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="栅格布局,每行等分为24列。">
                  <Icon type="question-circle" />
                  卡片宽度
                </Tooltip>
              }>
                {getFieldDecorator('width', {
                  initialValue: setting.width || 24,
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '宽度!'
                    }
                  ]
                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col>
            {appType !== 'mob' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择复式卡时,可配置鼠标悬浮时的显示信息。">
                  <Icon type="question-circle" />
                  卡片类型
                </Tooltip>
              }>
                {getFieldDecorator('type', {
                  initialValue: setting.type || 'simple'
                })(
                  <Radio.Group onChange={(e) => this.setState({ type: e.target.value })}>
                    <Radio value="simple">单卡</Radio>
                    <Radio value="multi">复式卡</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {this.state.type === 'multi' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="复式卡片鼠标悬浮信息的动画效果。">
                  <Icon type="question-circle" />
                  过渡效果
                </Tooltip>
              }>
                {getFieldDecorator('transform', {
                  initialValue: setting.transform || 'up'
                })(
                  <Select>
                    <Select.Option value="up">向上滑动</Select.Option>
                    <Select.Option value="down">向下滑动</Select.Option>
                    <Select.Option value="left">向左滑动</Select.Option>
                    <Select.Option value="right">向右滑动</Select.Option>
                    <Select.Option value="scale">缩放</Select.Option>
                    <Select.Option value="opacity">透明度</Select.Option>
                    <Select.Option value="rotateX">纵向展开</Select.Option>
                    <Select.Option value="rotateY">横向展开</Select.Option>
                  </Select>
                )}
              </Form.Item>
            </Col> : null}
            {cards.subtype === 'propcard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="卡片点击时,向其他组件传递的BID值。">
                  <Icon type="question-circle" />
                  主键值
                </Tooltip>
              }>
                {getFieldDecorator('primaryId', {
                  initialValue: setting.primaryId || ''
                })(<Input placeholder="" autoComplete="off" onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col> : null}
            <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="当选择触发按钮时,只有当卡片中只存在一个按钮时有效。">
                  <Icon type="question-circle" />
                  点击事件
                </Tooltip>
              }>
                {getFieldDecorator('click', {
                  initialValue: click
                })(
                  <Radio.Group style={{whiteSpace: 'nowrap'}} onChange={(e) => this.setState({click: e.target.value})}>
                    <Radio value="">无</Radio>
                    <Radio value="menu">菜单</Radio>
                    <Radio value="link">链接</Radio>
                    <Radio value="button">按钮</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col>
            {!appType && click === 'menu' ? <Col span={12}>
              <Form.Item label="菜单">
                {getFieldDecorator('menu', {
                  initialValue: setting.menu || [],
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.select'] + '菜单!'
                    }
                  ]
                })(
                  <Cascader options={menulist} placeholder=""/>
                )}
              </Form.Item>
            </Col> : null}
            {appType && click === 'menu' ? <Col span={12}>
              <Form.Item label="关联菜单">
                {getFieldDecorator('menu', {
                  initialValue: setting.menu || '',
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.select'] + '关联菜单!'
                    }
                  ]
                })(
                  <Select
                    showSearch
                    filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  >
                    {menulist.map(option =>
                      <Select.Option key={option.MenuID} value={option.MenuID}>{option.MenuName}</Select.Option>
                    )}
                  </Select>
                )}
              </Form.Item>
            </Col> : null}
            {click === 'link' ? <Col span={24} className="textarea">
              <Form.Item label="链接">
                {getFieldDecorator('linkurl', {
                  initialValue: setting.linkurl || '',
                  rules: [
                    {
                      required: true,
                      message: this.props.dict['form.required.input'] + '链接!'
                    }
                  ]
                })( <TextArea rows={2}/> )}
              </Form.Item>
            </Col> : null}
            {appType === 'pc' && click !== '' && click !== 'button' ? <Col span={12}>
              <Form.Item label="打开方式">
                {getFieldDecorator('open', {
                  initialValue: setting.open || 'blank'
                })(
                  <Radio.Group>
                    <Radio value="blank">新窗口</Radio>
                    <Radio value="self">当前窗口</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
            {click !== '' && click !== 'button' ? <Col span={12}>
              <Form.Item label="参数拼接">
                {getFieldDecorator('joint', {
                  initialValue: setting.joint || 'true'
                })(
                  <Radio.Group>
                    <Radio value="true">是</Radio>
                    <Radio value="false">否</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
            </Col> : null}
          </Row>
        </Form>
      </div>
    )
  }
}
export default Form.create()(MainSearch)
export default Form.create()(SettingForm)