king
2019-12-03 343e35d61733028e884bc60963183983154ca093
2019-12-03-01
14个文件已修改
4个文件已添加
867 ■■■■■ 已修改文件
src/assets/css/main.scss 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/editthdmenu/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/comtable.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/comtable.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/mainSearch/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/mainTable/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/colspanform/index.jsx 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/colspanform/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/dragelement/card.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/dragelement/index.jsx 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.scss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/source.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/transferform/index.jsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/transferform/index.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 195 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/main.scss
@@ -85,6 +85,22 @@
  z-index: 1080;
}
// 重置穿梭框滚动条
.ant-transfer-list-content::-webkit-scrollbar {
  width: 7px;
}
.ant-transfer-list-content::-webkit-scrollbar-thumb {
  border-radius: 5px;
  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
  background: rgba(0, 0, 0, 0.13);
}
.ant-transfer-list-content::-webkit-scrollbar-track {
  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
  border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, 0.07);
  background: rgba(0, 0, 0, 0);
}
// 重置时间插件时间滚动条
.ant-calendar-time-picker-select:hover::-webkit-scrollbar {
  width: 7px;
src/components/sidemenu/editthdmenu/index.jsx
@@ -43,6 +43,7 @@
    tabview: '', // 选择模板窗口(template)、基础表格配置(CommonTable)
    formlist: null,
    editMenu: null, // 编辑菜单
    editAction: null, // 编辑按钮
    thawMvisible: false, // 解除冻结模态框
    confirmLoading: false, // 提交中。。。
    dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
@@ -337,10 +338,12 @@
            _config = window.decodeURIComponent(window.atob(temp.LongParam))
            try {
              _config = JSON.parse(_config)
              _config.type = 'user'
            } catch (e) {
              _config = ''
            }
          }
          return {
            title: temp.MenuName,
            type: temp.Template,
@@ -363,10 +366,11 @@
  handleSubConfig = (item, originMenu, config) => {
    if (item.OpenType === 'pop') {
      // this.setState({
      //   editMenu: originMenu,
      //   tabview: 'Modal'
      // })
      this.setState({
        editMenu: originMenu,
        editAction: item,
        tabview: 'Modal'
      })
    }
    console.log(item)
    console.log(originMenu)
@@ -474,8 +478,7 @@
        {this.state.tabview === 'Modal' &&
          <ModalConfig
            menu={this.state.editMenu}
            supMenu={this.props.supMenu}
            supMenuList={this.props.supMenuList}
            editAction={this.state.editAction}
            handleConfig={this.handleConfig}
          />
        }
src/locales/en-US/comtable.js
@@ -24,6 +24,10 @@
  'header.form.search.placeholder': '请添加搜索条件',
  'header.form.action.placeholder': '请添加按钮',
  'header.form.column.placeholder': '请添加显示列',
  'header.form.column.source': '显示列',
  'header.form.column.target': '已添加',
  'header.form.column.itemUnit': '项',
  'header.form.column.itemsUnit': '项',
  'header.form.name': 'Name',
  'header.form.field': '字段',
  'header.form.func': '函数名',
@@ -46,6 +50,7 @@
  'header.form.type': 'Type',
  'header.form.text': 'Text',
  'header.form.picture': '图片',
  'header.form.colspan': '合并列',
  'header.form.select': 'Select',
  'header.form.link': '关联菜单',
  'header.form.dateday': 'Date(Day)',
src/locales/zh-CN/comtable.js
@@ -24,6 +24,10 @@
  'header.form.search.placeholder': '请添加搜索条件',
  'header.form.action.placeholder': '请添加按钮',
  'header.form.column.placeholder': '请添加显示列',
  'header.form.column.source': '显示列',
  'header.form.column.target': '已添加',
  'header.form.column.itemUnit': '项',
  'header.form.column.itemsUnit': '项',
  'header.form.name': '名称',
  'header.form.field': '字段',
  'header.form.func': '函数名',
@@ -46,6 +50,7 @@
  'header.form.type': '类型',
  'header.form.text': '文本',
  'header.form.picture': '图片',
  'header.form.colspan': '合并列',
  'header.form.select': '选择',
  'header.form.link': '关联菜单',
  'header.form.dateday': '日期(天)',
src/tabviews/commontable/index.jsx
@@ -69,10 +69,36 @@
      let _search = Utils.mainjointsearchkey(config.search)
      let _arrField = []
      let _columns = []
      let _hideCol = []
      let colMap = new Map()
      config.columns.forEach(col => {
        if (col.field) {
          _arrField.push(col.field)
        }
        if (col.type === 'colspan' && col.sublist) { // 筛选隐藏列
          _hideCol = _hideCol.concat(col.sublist)
        } else if (col.Hide === 'true') {
          _hideCol.push(col.uuid)
        }
        colMap.set(col.uuid, col)
      })
      config.columns.forEach(col => {
        if (_hideCol.includes(col.uuid)) return
        if (col.type === 'colspan' && col.sublist) {
          let _col = JSON.parse(JSON.stringify(col))
          let subColumn = []
          _col.sublist.forEach(sub => {
            if (colMap.has(sub)) {
              subColumn.push(colMap.get(sub))
            }
          })
          _col.subColumn = subColumn
          _columns.push(_col)
        } else {
          _columns.push(col)
        }
      })
@@ -81,7 +107,7 @@
        setting: config.setting,
        searchlist: config.search,
        actions: config.action,
        columns: config.columns,
        columns: _columns,
        arr_field: _arrField.join(','),
        search: _search ? 'where (' + _search + ')' : '',
        orderColumn: config.setting.orderColumn,
src/tabviews/commontable/mainSearch/index.jsx
@@ -216,7 +216,7 @@
        search.push({
          type: this.state.style[key],
          key: key,
          value: values[key],
          value: values[key].replace(/(^\s*|\s*$)/ig, ''),
          match: this.state.match[key]
        })
      }
src/tabviews/commontable/mainTable/index.jsx
@@ -30,9 +30,7 @@
    const { columns } = this.props
    let _columns = []
    columns.forEach((item, index) => {
      // console.log(item)
      if (item.Hide === 'true') return
      console.log(item)
      let cell = {
        align: item.Align,
        dataIndex: item.field || item.uuid,
src/templates/comtableconfig/colspanform/index.jsx
New file
@@ -0,0 +1,149 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, notification, InputNumber, Select, Radio } from 'antd'
import TransferForm from '../transferform'
import './index.scss'
class MainSearch extends Component {
  static propTpyes = {
    dict: PropTypes.object, // 字典项
    columns: PropTypes.array,
    card: PropTypes.any
  }
  state = {
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let targetKeys = this.refs['column-transfer'].state.targetKeys
          if (targetKeys.length === 0) {
            notification.warning({
              top: 92,
              message: '请添加显示列',
              duration: 10
            })
            return
          }
          delete values.type
          let _card = {...this.props.card, ...values, sublist: targetKeys}
          resolve({
            type: 'columns',
            values: _card
          })
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 18 }
      }
    }
    return (
      <Form {...formItemLayout} className="ant-advanced-search-form commontable-column-form" id="columncolspan">
        <Row gutter={24}>
          <Col span={12}>
            <Form.Item label={this.props.dict['header.form.name']}>
              {getFieldDecorator('label', {
                initialValue: this.props.card.label,
                rules: [
                  {
                    required: true,
                    message: this.props.dict['form.required.input'] + this.props.dict['header.form.name'] + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" />)}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label={this.props.dict['header.form.type']}>
              {getFieldDecorator('type', {
                initialValue: this.props.dict['header.form.colspan'],
                rules: [
                  {
                    required: true,
                    message: this.props.dict['form.required.input'] + this.props.dict['header.form.type'] + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={true}/>)}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label={this.props.dict['header.form.align']}>
              {getFieldDecorator('Align', {
                initialValue: this.props.card.Align,
                rules: [
                  {
                    required: true,
                    message: this.props.dict['form.required.select'] + this.props.dict['header.form.align'] + '!'
                  }
                ]
              })(
                <Select
                  getPopupContainer={() => document.getElementById('columncolspan')}
                >
                  <Select.Option value="left">{this.props.dict['header.form.alignLeft']}</Select.Option>
                  <Select.Option value="right">{this.props.dict['header.form.alignRight']}</Select.Option>
                  <Select.Option value="center">{this.props.dict['header.form.alignCenter']}</Select.Option>
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label={this.props.dict['header.form.columnWidth']}>
              {getFieldDecorator('Width', {
                initialValue: this.props.card.Width,
                rules: [
                  {
                    required: true,
                    message: this.props.dict['form.required.input'] + this.props.dict['header.form.columnWidth'] + '!'
                  }
                ]
              })(<InputNumber min={1} max={1000} precision={0} />)}
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item label={this.props.dict['header.form.Hide']}>
              {getFieldDecorator('Hide', {
                initialValue: this.props.card.Hide,
                rules: [
                  {
                    required: true,
                    message: this.props.dict['form.required.select'] + this.props.dict['header.form.Hide'] + '!'
                  }
                ]
              })(
                <Radio.Group>
                  <Radio value="true">{this.props.dict['header.form.true']}</Radio>
                  <Radio value="false">{this.props.dict['header.form.false']}</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          <Col span={24}>
            <TransferForm dict={this.props.dict} columns={this.props.columns} ref="column-transfer" selected={this.props.card.sublist}/>
          </Col>
        </Row>
      </Form>
    )
  }
}
export default Form.create()(MainSearch)
src/templates/comtableconfig/colspanform/index.scss
New file
@@ -0,0 +1,9 @@
.ant-advanced-search-form.commontable-column-form {
  min-height: 190px;
  .ant-form-item {
    margin-bottom: 15px;
    .ant-input-number {
      width: 100%;
    }
  }
}
src/templates/comtableconfig/dragelement/card.jsx
@@ -7,7 +7,7 @@
const { MonthPicker, WeekPicker, RangePicker } = DatePicker
const Card = ({ id, type, card, moveCard, findCard, editCard, copyCard, hasDrop }) => {
const Card = ({ id, type, card, moveCard, findCard, editCard, delCard, copyCard, hasDrop }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: ItemTypes[type], id, originalIndex },
@@ -35,6 +35,10 @@
  const edit = () => {
    editCard(id)
  }
  const del = () => {
    delCard(id)
  }
  const copy = () => {
@@ -109,6 +113,7 @@
        }
      </div>
      <Icon className="edit" type="edit" onClick={edit} />
      <Icon className="edit close" type="close" onClick={del} />
      {type === 'action' && <Icon className="edit copy" type="copy" onClick={copy} />}
    </div>
  )
src/templates/comtableconfig/dragelement/index.jsx
@@ -7,7 +7,7 @@
import ItemTypes from './itemtypes'
import './index.scss'
const Container = ({list, setting, type, placeholder, handleList, handleMenu, copyElement }) => {
const Container = ({list, setting, type, placeholder, handleList, handleMenu, deleteMenu, copyElement }) => {
  let target = null
  const [cards, setCards] = useState(list)
  const moveCard = (id, atIndex) => {
@@ -28,6 +28,11 @@
  const editCard = id => {
    const { card } = findCard(id)
    handleMenu(card)
  }
  const delCard = id => {
    const { card } = findCard(id)
    deleteMenu({card: card, type: type})
  }
  const copyCard = id => {
@@ -127,6 +132,10 @@
        newcard.IsSort = 'true'
        newcard.type = item.subType
        newcard.Width = 120
        if (item.subType === 'colspan') {
          newcard.sublist = []
          newcard.IsSort = 'false'
        }
      }
      
      let indexes = cards.map(car => {return car.id})
@@ -157,13 +166,31 @@
    }
  })
  let columns = []
  if (type === 'columns' && cards.length > 10) {
    let number = Math.ceil(cards.length / Math.ceil(cards.length / 10))
    for (let i = 0, len = cards.length; i < len; i += number) {
      columns.push(cards.slice(i, i + number))
  let _colCards = []
  // 过滤合并列
  if (type === 'columns') {
    let _hideCol = []
    cards.forEach(col => {
      if (col.type === 'colspan' && col.sublist) {
        _hideCol = _hideCol.concat(col.sublist)
      }
    })
    cards.forEach(col => {
      if (!_hideCol.includes(col.uuid)) {
        _colCards.push(col)
      }
    })
  }
  // 显示列分行
  if (type === 'columns' && _colCards.length > 10) {
    let number = Math.ceil(_colCards.length / Math.ceil(_colCards.length / 10))
    for (let i = 0, len = _colCards.length; i < len; i += number) {
      columns.push(_colCards.slice(i, i + number))
    }
  } else if (type === 'columns') {
    columns.push(cards)
    columns.push(_colCards)
  }
  
  return (
@@ -176,6 +203,7 @@
          card={card}
          moveCard={moveCard}
          editCard={editCard}
          delCard={delCard}
          copyCard={copyCard}
          findCard={findCard}
          hasDrop={hasDrop}
@@ -190,12 +218,13 @@
            card={card}
            moveCard={moveCard}
            editCard={editCard}
            delCard={delCard}
            findCard={findCard}
            hasDrop={hasDrop}
          />
        </Col>
      ))}
      {type === 'columns' && cards.length > 0 &&
      {type === 'columns' && _colCards.length > 0 &&
        columns.map((column, i) => (
          <div key={i} className="column-box">
            {/* 多选 */}
@@ -216,6 +245,7 @@
                card={card}
                moveCard={moveCard}
                editCard={editCard}
                delCard={delCard}
                findCard={findCard}
                hasDrop={hasDrop}
              />
src/templates/comtableconfig/index.jsx
@@ -10,6 +10,7 @@
import SearchForm from './searchform'
import ActionForm from './actionform'
import ColumnForm from './columnform'
import ColspanForm from './colspanform'
import SettingForm from './settingform'
import EditCard from './editcard'
import MenuForm from './menuform'
@@ -55,7 +56,8 @@
    closeVisible: false, // 关闭模态框
    tables: [], // 可用表名
    selectedTables: [], // 已选表名
    originMenu: null // 原始菜单
    originMenu: null, // 原始菜单
    originActions: null
  }
  /**
@@ -82,7 +84,13 @@
      _config = _LongParam
    }
    let _oriActions = _config.action
    if (_config.type === 'user' || _config.type === 'system') {
      _oriActions = []
    }
    this.setState({
      originActions: _oriActions,
      config: _config,
      operaType: _type,
      originMenu: JSON.parse(JSON.stringify({...menu})),
@@ -640,95 +648,103 @@
  }
  handleColumn = (card) => {
    this.setState({
      visible: true,
      formtemp: 'columns',
      card: card,
      formlist: [
        {
          type: 'text',
          key: 'label',
          label: this.state.dict['header.form.name'],
          initVal: card.label,
          required: true
        },
        {
          type: 'text',
          key: 'field',
          label: this.state.dict['header.form.field'],
          initVal: card.field,
          required: true,
          readonly: false
        },
        {
          type: 'select',
          key: 'type',
          label: this.state.dict['header.form.type'],
          initVal: card.type,
          required: true,
          options: [{
            MenuID: 'text',
            text: this.state.dict['header.form.text']
          }, {
            MenuID: 'picture',
            text: this.state.dict['header.form.picture']
          }]
        },
        {
          type: 'select',
          key: 'Align',
          label: this.state.dict['header.form.align'],
          initVal: card.Align,
          required: true,
          options: [{
            MenuID: 'left',
            text: this.state.dict['header.form.alignLeft']
          }, {
            MenuID: 'right',
            text: this.state.dict['header.form.alignRight']
          }, {
            MenuID: 'center',
            text: this.state.dict['header.form.alignCenter']
          }]
        },
        {
          type: 'radio',
          key: 'Hide',
          label: this.state.dict['header.form.Hide'],
          initVal: card.Hide,
          required: true,
          options: [{
            MenuID: 'true',
            text: this.state.dict['header.form.true']
          }, {
            MenuID: 'false',
            text: this.state.dict['header.form.false']
          }]
        },
        {
          type: 'select',
          key: 'IsSort',
          label: this.state.dict['header.form.IsSort'],
          initVal: card.IsSort,
          required: true,
          options: [{
            MenuID: 'true',
            text: this.state.dict['header.form.true']
          }, {
            MenuID: 'false',
            text: this.state.dict['header.form.false']
          }]
        },
        {
          type: 'number',
          key: 'Width',
          decimal: 0,
          label: this.state.dict['header.form.columnWidth'],
          initVal: card.Width,
          required: true
        }
      ]
    })
    if (card.type !== 'colspan') {
      this.setState({
        visible: true,
        formtemp: 'columns',
        card: card,
        formlist: [
          {
            type: 'text',
            key: 'label',
            label: this.state.dict['header.form.name'],
            initVal: card.label,
            required: true
          },
          {
            type: 'text',
            key: 'field',
            label: this.state.dict['header.form.field'],
            initVal: card.field,
            required: true,
            readonly: false
          },
          {
            type: 'select',
            key: 'type',
            label: this.state.dict['header.form.type'],
            initVal: card.type,
            required: true,
            options: [{
              MenuID: 'text',
              text: this.state.dict['header.form.text']
            }, {
              MenuID: 'picture',
              text: this.state.dict['header.form.picture']
            }]
          },
          {
            type: 'select',
            key: 'Align',
            label: this.state.dict['header.form.align'],
            initVal: card.Align,
            required: true,
            options: [{
              MenuID: 'left',
              text: this.state.dict['header.form.alignLeft']
            }, {
              MenuID: 'right',
              text: this.state.dict['header.form.alignRight']
            }, {
              MenuID: 'center',
              text: this.state.dict['header.form.alignCenter']
            }]
          },
          {
            type: 'radio',
            key: 'Hide',
            label: this.state.dict['header.form.Hide'],
            initVal: card.Hide,
            required: true,
            options: [{
              MenuID: 'true',
              text: this.state.dict['header.form.true']
            }, {
              MenuID: 'false',
              text: this.state.dict['header.form.false']
            }]
          },
          {
            type: 'select',
            key: 'IsSort',
            label: this.state.dict['header.form.IsSort'],
            initVal: card.IsSort,
            required: true,
            options: [{
              MenuID: 'true',
              text: this.state.dict['header.form.true']
            }, {
              MenuID: 'false',
              text: this.state.dict['header.form.false']
            }]
          },
          {
            type: 'number',
            key: 'Width',
            decimal: 0,
            label: this.state.dict['header.form.columnWidth'],
            initVal: card.Width,
            required: true
          }
        ]
      })
    } else {
      this.setState({
        visible: true,
        formtemp: 'columns',
        card: card
      })
    }
  }
  handleSubmit = () => {
@@ -783,23 +799,32 @@
    })
  }
  deleteElement = () => {
    let _config = this.state.config
    _config[this.state.formtemp] = _config[this.state.formtemp].filter(item => {
      if (item.uuid === this.state.card.uuid) {
        return false
      } else {
        return true
      }
    })
    this.setState({
      config: _config,
      [this.state.formtemp + 'loading']: true,
      visible: false
    }, () => {
      this.setState({
        [this.state.formtemp + 'loading']: false
      })
  deleteElement = (element) => {
    let _this = this
    confirm({
      content: `确定删除<<${element.card.label}>>吗?`,
      okText: this.state.dict['header.confirm'],
      cancelText: this.state.dict['header.cancel'],
      onOk() {
        let _config = JSON.parse(JSON.stringify(_this.state.config))
        _config[element.type] = _config[element.type].filter(item => {
          if (item.uuid === element.card.uuid) {
            return false
          } else {
            return true
          }
        })
        _this.setState({
          config: _config,
          [element.type + 'loading']: true,
          visible: false
        }, () => {
          _this.setState({
            [element.type + 'loading']: false
          })
        })
      },
      onCancel() {}
    })
  }
@@ -807,6 +832,9 @@
    this.props.handleConfig('template')
  }
  /**
   * @description 三级菜单保存
   */
  submitConfig = () => {
    const { menu } = this.props
    const { config, originMenu } = this.state
@@ -841,6 +869,9 @@
      let _config = {...config, tables: this.state.selectedTables}
      let _pageParam = {...menu.PageParam, OpenType: res.opentype}
      // 保存时删除配置类型,system 、user
      delete _config.type
      try {
        _LongParam = window.btoa(window.encodeURIComponent(JSON.stringify(_config)))
      } catch (e) {
@@ -852,7 +883,7 @@
        return
      }
      if (this.state.operaType === 'add') {
      if (this.state.operaType === 'add') { // 新建菜单
        let param = {
          func: 'sPC_TrdMenu_Add',
          ParentID: res.parentId,
@@ -897,7 +928,7 @@
            })
          }
        })
      } else {
      } else { // 修改菜单
        let param = {
          func: 'sPC_TrdMenu_Upt',
          ParentID: res.parentId,
@@ -953,6 +984,15 @@
        duration: 10
      })
    })
  }
  /**
   * @description 保存或修改菜单按钮
   */
  submitAction = () => {
    if (!is(fromJS(this.state.originActions), fromJS())) {
    }
  }
  cancelConfig = () => {
@@ -1461,6 +1501,7 @@
                    placeholder={this.state.dict['header.form.search.placeholder']}
                    handleList={this.handleList}
                    handleMenu={this.handleSearch}
                    deleteMenu={this.deleteElement}
                  /> : null
                }
              </div>
@@ -1473,6 +1514,7 @@
                    handleList={this.handleList}
                    handleMenu={this.handleAction}
                    copyElement={this.handleAction}
                    deleteMenu={this.deleteElement}
                  /> : null
                }
              </div>
@@ -1485,6 +1527,7 @@
                    placeholder={this.state.dict['header.form.column.placeholder']}
                    handleList={this.handleList}
                    handleMenu={this.handleColumn}
                    deleteMenu={this.deleteElement}
                  /> : null
                }
              </div>
@@ -1497,11 +1540,12 @@
          visible={this.state.visible}
          width={700}
          onCancel={() => { this.setState({ visible: false }) }}
          footer={[
            <Button key="delete" type="danger" onClick={this.deleteElement}>{this.state.dict['header.delete']}</Button>,
            <Button key="cancel" onClick={() => { this.setState({ visible: false }) }}>{this.state.dict['header.cancel']}</Button>,
            <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['header.confirm']}</Button>
          ]}
          onOk={this.handleSubmit}
          // footer={[
          //   <Button key="delete" type="danger" onClick={this.deleteElement}>{this.state.dict['header.delete']}</Button>,
          //   <Button key="cancel" onClick={() => { this.setState({ visible: false }) }}>{this.state.dict['header.cancel']}</Button>,
          //   <Button key="confirm" type="primary" onClick={this.handleSubmit}>{this.state.dict['header.confirm']}</Button>
          // ]}
          destroyOnClose
        >
          {this.state.formtemp === 'search' ?
@@ -1520,7 +1564,7 @@
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'columns' ?
          {this.state.formtemp === 'columns' && this.state.card.type !== 'colspan' ?
            <ColumnForm
              dict={this.state.dict}
              card={this.state.card}
@@ -1528,6 +1572,14 @@
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
          {this.state.formtemp === 'columns' && this.state.card.type === 'colspan' ?
            <ColspanForm
              dict={this.state.dict}
              card={this.state.card}
              columns={this.state.config.columns}
              wrappedComponentRef={(inst) => this.formRef = inst}
            /> : null
          }
        </Modal>
        {/* 根据字段名添加显示列及搜索条件 */}
        <Modal
src/templates/comtableconfig/index.scss
@@ -193,8 +193,15 @@
            position: absolute;
            left: 0;
            top: 5px;
            color: #1890ff;
            cursor: pointer;
            display: none;
            // border: 1px solid #1890ff;
            // border-radius: 20px;
          }
          .edit.close {
            left: 20px;
            color: #ff4d4f;
          }
        }
        .page-card:hover {
@@ -225,11 +232,17 @@
            position: absolute;
            left: 0;
            top: 0px;
            color: #1890ff;
            cursor: pointer;
            display: none;
          }
          .edit.close {
            left: 40px;
            color: #ff4d4f;
          }
          .edit.copy {
            left: 20px;
            color: #26C281;
          }
          button {
            cursor: move;
@@ -295,9 +308,14 @@
              position: absolute;
              left: 0;
              top: 0px;
              color: #1890ff;
              cursor: pointer;
              display: none;
            }
            .edit.close {
              left: 20px;
              color: #ff4d4f;
            }
            .ant-checkbox-inner {
              margin-top: 14px;
              margin-left: calc(50% - 8px);
src/templates/comtableconfig/source.jsx
@@ -313,6 +313,12 @@
      label: CommonDict['header.form.picture'],
      subType: 'picture',
      url: ''
    },
    {
      type: 'columns',
      label: CommonDict['header.form.colspan'],
      subType: 'colspan',
      url: ''
    }
  ]
}
src/templates/comtableconfig/transferform/index.jsx
New file
@@ -0,0 +1,75 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Transfer } from 'antd'
import './index.scss'
class TransferForm extends Component {
  static propTypes = {
    columns: PropTypes.array,
    selected: PropTypes.array,
    dict: PropTypes.object, // 字典项
  }
  state = {
    data: [],
    targetKeys: [],
    selectedKeys: []
  }
  handleChange = (nextTargetKeys, direction, moveKeys) => {
    this.setState({ targetKeys: nextTargetKeys })
  }
  handleSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
    this.setState({ selectedKeys: [...sourceSelectedKeys, ...targetSelectedKeys] })
  }
  UNSAFE_componentWillMount() {
    let datas = new Map()
    this.props.columns.forEach(item => {
      if (item.field) {
        datas.set(item.uuid, item)
      }
    })
    let selecteds = []
    this.props.selected.forEach(item => {
      if (datas.has(item)) {
        selecteds.push(item)
        // datas.delete(item)
      }
    })
    this.setState({
      data: [...datas.values()].map(item => {
        return {
          key: item.uuid,
          title: item.label,
          description: ''
        }
      }),
      targetKeys: selecteds
    })
  }
  render() {
    const { targetKeys, selectedKeys } = this.state
    return (
      <div className="common-table-columns-transfer">
        <Transfer
          dataSource={this.state.data}
          titles={[this.props.dict['header.form.column.source'], this.props.dict['header.form.column.target']]}
          targetKeys={targetKeys}
          locale={{itemUnit: this.props.dict['header.form.column.itemUnit'], itemsUnit: this.props.dict['header.form.column.itemsUnit']}}
          selectedKeys={selectedKeys}
          onChange={this.handleChange}
          onSelectChange={this.handleSelectChange}
          render={item => item.title}
        />
      </div>
    )
  }
}
export default TransferForm
src/templates/comtableconfig/transferform/index.scss
New file
@@ -0,0 +1,6 @@
.common-table-columns-transfer {
  padding-left: 18px;
  .ant-transfer-list {
    width: 296px;
  }
}
src/templates/modalconfig/index.jsx
@@ -3,15 +3,15 @@
import { is, fromJS } from 'immutable'
import { DndProvider } from 'react-dnd'
import HTML5Backend from 'react-dnd-html5-backend'
import { Button, Card, Modal, Collapse, notification, Select, List, Icon, Empty } from 'antd'
import DragElement from './dragelement'
import { Button, Card, Modal, Collapse, notification, Select, List, Icon } from 'antd'
// import DragElement from './dragelement'
import SourceElement from './dragelement/source'
import Api from '@/api'
import SearchForm from './searchform'
import ActionForm from './actionform'
import ColumnForm from './columnform'
import SettingForm from './settingform'
import EditCard from './editcard'
// import SearchForm from './searchform'
// import ActionForm from './actionform'
// import ColumnForm from './columnform'
// import SettingForm from './settingform'
// import EditCard from './editcard'
import MenuForm from './menuform'
import zhCN from '@/locales/zh-CN/comtable.js'
import enUS from '@/locales/en-US/comtable.js'
@@ -26,11 +26,9 @@
class ComTableConfig extends Component {
  static propTpyes = {
    type: PropTypes.string,
    menu: PropTypes.any,
    handleConfig: PropTypes.func,
    supMenuList: PropTypes.array,
    supMenu: PropTypes.object,
    editAction: PropTypes.object,
    handleConfig: PropTypes.func
  }
  state = {
@@ -42,7 +40,7 @@
    addType: '', // 添加类型-搜索条件或显示列
    tableColumns: [], // 表格显示列
    fields: null, // 搜索条件及显示列,可选字段
    menuformlist: null, // 基本信息表单字段
    modalformlist: null, // 基本信息表单字段
    formlist: null, // 搜索条件、按钮、显示列表单字段
    formtemp: '', // 表单类型,显示列、按钮、搜索条件
    card: null, // 编辑元素
@@ -58,43 +56,27 @@
  }
  UNSAFE_componentWillMount () {
    const {menu, supMenu} = this.props
    let _LongParam = menu.LongParam
    let _config = ''
    if (this.props.type === 'add' || !_LongParam) {
      _config = JSON.parse(JSON.stringify((Source.baseConfig)))
    } else {
      let _setting = Source.baseConfig.setting
      if (_LongParam.setting) {
        _setting = {..._setting, ..._LongParam.setting}
      }
      _LongParam.setting = _setting
      _config = _LongParam
    }
    const {menu, editAction} = this.props
    this.setState({
      operaType: this.props.type,
      originMenu: JSON.parse(JSON.stringify({...menu, ParentID: supMenu.MenuID})),
      config: _config,
      selectedTables: _config.tables || [],
      menuformlist: [
      // config: _config,
      // selectedTables: _config.tables || [],
      modalformlist: [
        {
          type: 'select',
          key: 'parentId',
          type: 'text',
          key: 'supMenu',
          label: this.state.dict['header.menu.supMenu'],
          initVal: this.props.supMenu.MenuID,
          initVal: menu.MenuName,
          required: true,
          readonly: false,
          options: this.props.supMenuList
          readonly: true,
        },
        {
          type: 'text',
          key: 'menuName',
          label: this.state.dict['header.menu.menuName'],
          initVal: menu.MenuName,
          key: 'btnName',
          label: '按钮名称',
          initVal: editAction.label,
          required: true,
          readonly: false
          readonly: true
        },
        {
          type: 'text',
@@ -102,63 +84,36 @@
          label: this.state.dict['header.menu.menuNo'],
          initVal: menu.MenuNo,
          required: true,
          readonly: false
          readonly: true
        },
        {
          type: 'select',
          type: 'text',
          key: 'opentype',
          label: this.state.dict['header.menu.openType'],
          initVal: menu.PageParam.OpenType,
          initVal: '弹窗(表单)',
          required: true,
          options: [{
            MenuID: 'newtab',
            text: this.state.dict['header.form.tab']
          }, {
            MenuID: 'newpage',
            text: this.state.dict['header.form.newpage']
          }]
          readonly: true
        }
      ]
    })
  }
  componentDidMount () {
    let _text = "select TbName ,Remark from sDataDictionary where IsKey!='' and Deleted =0"
    let _text = 'select TbName ,Remark from sDataDictionary where IsKey!=\'\' and Deleted =0'
    _text = Utils.formatOptions(_text)
    Api.getSystemConfig({func: 'sPC_Get_SelectedList', LText: _text, obj_name: ''}).then(res => {
      this.setState({
        tables: [
          {
            TbName: 'SRMPurchaseOrder',
            Remark: '采购单'
          },
          {
            TbName: 'sOrganizationAccount',
            Remark: '公司账号'
          },
          {
            TbName: 'sOrganization',
            Remark: '公司'
          },
          {
            TbName: 'BDFactory',
            Remark: '工厂主数据'
          },
          {
            TbName: 'BDWMSWareHouse',
            Remark: '库存地点主数据'
          },
          {
            TbName: 'BDFactoryPerson',
            Remark: '工厂联系人'
          },
          {
            TbName: 'BDWMSStockType',
            Remark: '存储类型'
          }
        ]
      })
    Api.getSystemConfig({func: 'sPC_Get_SelectedList', LText: _text, obj_name: 'data', arr_field: 'TbName,Remark'}).then(res => {
      if (res.status) {
        this.setState({
          tables: res.data
        })
      } else {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 10
        })
      }
    })
    let deffers = this.state.selectedTables.map(item => {
@@ -1161,7 +1116,7 @@
              <Panel header="基本信息" key="0" id="common-basedata">
                <MenuForm
                  dict={this.state.dict}
                  formlist={this.state.menuformlist}
                  formlist={this.state.modalformlist}
                  wrappedComponentRef={(inst) => this.menuformRef = inst}
                />
                <div className="ant-col ant-form-item-label">
@@ -1177,7 +1132,6 @@
                  showArrow={false}
                  getPopupContainer={() => document.getElementById('common-basedata')}
                  filterOption={(input, option) => {
                    console.log(option)
                    return option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                  }}
                > 
@@ -1196,60 +1150,25 @@
                  </List.Item>}
                />}
              </Panel>
              <Panel header="搜索" key="1">
              <Panel header="表单" key="1">
                <div className="search-element">
                  {Source.searchItems.map((item, index) => {
                    return (<SourceElement key={index} content={item}/>)
                  })}
                </div>
                <Button type="primary" block onClick={() => this.queryField('search')}>添加搜索条件</Button>
              </Panel>
              <Panel header="按钮" key="2">
                <div className="search-element">
                  {Source.actionItems.map((item, index) => {
                    return (<SourceElement key={index} content={item}/>)
                  })}
                </div>
                <div>
                  <p style={{marginTop: '20px', marginBottom: '10px', color: '#1890ff'}}>可配置按钮:</p>
                  {this.state.config.action.map((item, index) => {
                    if (item.OpenType === 'pop' && !item.origin) {
                      return (
                        <div key={index}>
                          <Button
                            icon={item.icon}
                            style={{marginBottom: '10px'}}
                            className={'mk-btn mk-' + item.class}
                            onClick={() => this.queryField('search')}
                          >{item.label}</Button>
                        </div>
                      )
                    } else {
                      return ''
                    }
                  })}
                </div>
              </Panel>
              <Panel header="显示列" key="3">
                <div className="search-element">
                  {Source.columnItems.map((item, index) => {
                    return (<SourceElement key={index} content={item}/>)
                  })}
                </div>
                <Button type="primary" block onClick={() => this.queryField('columns')}>添加显示列</Button>
                <Button type="primary" block onClick={() => this.queryField('search')}>添加表单</Button>
              </Panel>
            </Collapse>
          </div>
          <div className="setting">
            <Card title="页面配置" bordered={false} extra={
            <Card title="表单配置" bordered={false} extra={
              <div>
                <Button type="primary" onClick={this.changeTemplate}>{this.state.dict['header.menu.template.change']}</Button>
                <Button type="primary" onClick={this.submitConfig} loading={this.state.menuloading}>{this.state.dict['header.save']}</Button>
                <Button onClick={this.cancelConfig}>{this.state.dict['header.return']}</Button>
              </div>
            } style={{ width: '100%' }}>
              <Icon type="setting" onClick={this.changeSetting} />
              <div className="search-list">
              {/* <div className="search-list">
                {this.state.config.search && !this.state.searchloading &&
                <DragElement
                  list={this.state.config.search}
@@ -1258,31 +1177,11 @@
                  handleList={this.handleList}
                  handleMenu={this.handleSearch}
                />}
              </div>
              <div className="action-list">
                {this.state.config.action && !this.state.actionloading &&
                <DragElement
                  list={this.state.config.action}
                  type="action"
                  placeholder={this.state.dict['header.form.action.placeholder']}
                  handleList={this.handleList}
                  handleMenu={this.handleAction}
                />}
              </div>
              <div className="column-list">
                {this.state.config.columns && !this.state.columnsloading &&
                <DragElement
                  list={this.state.config.columns}
                  type="columns"
                  placeholder={this.state.dict['header.form.column.placeholder']}
                  handleList={this.handleList}
                  handleMenu={this.handleColumn}
                />}
              </div>
              </div> */}
            </Card>
          </div>
        </DndProvider>
        <Modal
        {/* <Modal
          title={this.state.dict['header.edit']}
          visible={this.state.visible}
          width={700}
@@ -1359,7 +1258,7 @@
          destroyOnClose
        >
          菜单配置已修改,是否保存配置信息?
        </Modal>
        </Modal> */}
      </div>
    )
  }
src/utils/utils.js
@@ -138,6 +138,7 @@
      let reg  =  new RegExp('(^|\\s)' + item.key + '(\\s|$)', 'ig')
      value = value.replace(reg, item.value)
    })
    value = value.replace(/%/ig, 'mpercent')
    value = value.replace(/(^\s|\s$)/ig, '')
    value = window.btoa(window.encodeURIComponent(value))
    let index = Math.floor(Math.random() * value.length)