king
2021-07-18 d9e822b0f72f8e232c7836f366e80bf3be25c4d8
2021-07-18
6个文件已修改
4个文件已添加
504 ■■■■■ 已修改文件
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/popview/index.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/replaceField/index.jsx 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/replaceField/index.scss 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/replaceField/settingform/index.jsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/replaceField/settingform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/views/interface/index.jsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pcdesign/index.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -268,7 +268,7 @@
      readonly: false
    },
    {
      type: 'radio',
      type: 'select',
      key: 'lenWidRadio',
      label: '长宽比',
      initVal: card.lenWidRadio || '1:1',
src/menu/popview/index.jsx
@@ -21,6 +21,7 @@
const MenuForm = asyncComponent(() => import('./menuform'))
const SourceWrap = asyncComponent(() => import('@/menu/modulesource'))
const MenuShell = asyncComponent(() => import('@/menu/menushell'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const BgController = asyncComponent(() => import('@/menu/bgcontroller'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const PaddingController = asyncComponent(() => import('@/menu/padcontroller'))
@@ -528,6 +529,18 @@
    window.GLOB.customMenu = config
  }
  resetConfig = (config) => {
    this.setState({
      config: {...config, components: []},
    }, () => {
      this.setState({
        config: config
      })
    })
    window.GLOB.customMenu = config
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   */
@@ -582,6 +595,7 @@
              <div> {config && config.MenuName} </div>
            } bordered={false} extra={
              <div>
                <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                <StyleCombControlButton menu={config} />
                <PasteController type="menu" Tab={null} insert={this.insert} />
                {config ? <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config.enabled} onChange={this.onEnabledChange} /> : null}
src/menu/replaceField/index.jsx
New file
@@ -0,0 +1,349 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Modal, Button, notification } from 'antd'
import moment from 'moment'
import Api from '@/api'
import options from '@/store/options.js'
import Utils from '@/utils/utils.js'
import SettingForm from './settingform'
import { queryTableSql } from '@/utils/option.js'
import './index.scss'
class ReplaceField extends Component {
  static propTpyes = {
    type: PropTypes.string,
    config: PropTypes.object,
    updateConfig: PropTypes.func
  }
  state = {
    visible: false,
    loadingTable: false,
    confirming: false,
    tables: [],
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  trigger = () => {
    const { tables } = this.state
    if (tables.length === 0) {
      let param = {
        func: 'sPC_Get_SelectedList',
        LText: queryTableSql,
        obj_name: 'data',
        arr_field: 'TbName,Remark'
      }
      param.LText = Utils.formatOptions(param.LText)
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
      param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp) // 云端数据验证
      if (options.cloudServiceApi) { // 且存在云端地址
        param.rduri = options.cloudServiceApi
        param.userid = sessionStorage.getItem('CloudUserID') || ''
        param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
      }
      this.setState({
        loadingTable: true
      })
      Api.getSystemCacheConfig(param).then(res => {
        if (res.status) {
          this.setState({
            visible: true,
            confirming: false,
            tables: res.data,
            loadingTable: false
          })
        } else {
          this.setState({
            confirming: false,
            loadingTable: false
          })
          notification.warning({
            top: 92,
            message: res.message,
            duration: 5
          })
        }
      })
    } else {
      this.setState({
        confirming: false,
        visible: true
      })
    }
  }
  submit = () => {
    let config = fromJS(this.props.config).toJS()
    this.settingRef.handleConfirm().then(res => {
      this.setState({confirming: true})
      let param = {func: 'sPC_Get_FieldName', TBName: res.table}
      if (options.cloudServiceApi) { // 且存在云端地址
        param.rduri = options.cloudServiceApi
        param.userid = sessionStorage.getItem('CloudUserID') || ''
        param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
      }
      Api.getSystemCacheConfig(param).then(result => {
        if (!result.status) {
          this.setState({
            confirming: false
          })
          notification.warning({
            top: 92,
            message: result.message,
            duration: 5
          })
          return
        }
        let map = {}
        result.FDName.forEach(item => {
          if (/NVARCHAR|INT|Decimal/ig.test(item.FieldType)) {
            item.datatype = item.FieldType
          }
          map[item.FieldDec] = item
        })
        if (this.props.type === 'custom') {
          let _replace = (components) => {
            return components.map(item => {
              if (item.type === 'tabs') {
                item.subtabs.forEach(tab => {
                  tab.components = _replace(tab.components)
                })
                return item
              } else if (item.type === 'group') {
                item.components = _replace(item.components)
                return item
              }
              if (item.columns) {
                item.columns = item.columns.map(col => {
                  if (map[col.field]) {
                    col.field = map[col.field].FieldName
                    if (map[col.field].datatype) {
                      col.datatype = map[col.field].datatype
                    }
                  }
                  return col
                })
              }
              if (item.search) {
                item.search = item.search.map(col => {
                  if (map[col.field]) {
                    col.field = map[col.field].FieldName
                  }
                  return col
                })
              }
              if (item.action) {
                item.action.forEach(m => {
                  if (m.modal && m.modal.fields) {
                    m.modal.fields = m.modal.fields.map(col => {
                      if (map[col.field]) {
                        col.field = map[col.field].FieldName
                      }
                      return col
                    })
                  }
                })
              }
              if (item.subcards) {
                item.subcards.forEach(card => {
                  if (card.elements) {
                    card.elements = card.elements.map(m => {
                      if (m.datatype === 'dynamic' && map[m.field]) {
                        m.field = map[m.field].FieldName
                      }
                      if (m.modal && m.modal.fields) {
                        m.modal.fields = m.modal.fields.map(col => {
                          if (map[col.field]) {
                            col.field = map[col.field].FieldName
                          }
                          return col
                        })
                      }
                      return m
                    })
                  }
                  if (card.backElements) {
                    card.backElements = card.backElements.map(m => {
                      if (m.datatype === 'dynamic' && map[m.field]) {
                        m.field = map[m.field].FieldName
                      }
                      if (m.modal && m.modal.fields) {
                        m.modal.fields = m.modal.fields.map(col => {
                          if (map[col.field]) {
                            col.field = map[col.field].FieldName
                          }
                          return col
                        })
                      }
                      return m
                    })
                  }
                })
              }
              if (item.elements) {
                item.elements = item.elements.map(m => {
                  if (m.datatype === 'dynamic' && map[m.field]) {
                    m.field = map[m.field].FieldName
                  }
                  if (m.modal && m.modal.fields) {
                    m.modal.fields = m.modal.fields.map(col => {
                      if (map[col.field]) {
                        col.field = map[col.field].FieldName
                      }
                      return col
                    })
                  }
                  return m
                })
              }
              if (item.plot) {
                if (item.plot.Xaxis && map[item.plot.Xaxis]) {
                  item.plot.Xaxis = map[item.plot.Xaxis].FieldName
                }
                // 统计图
                if (item.plot.InfoValue && map[item.plot.InfoValue]) {
                  item.plot.InfoValue = map[item.plot.InfoValue].FieldName
                }
                if (item.plot.InfoType && map[item.plot.InfoType]) {
                  item.plot.InfoType = map[item.plot.InfoType].FieldName
                }
                // 占比图
                if (item.plot.valueField && map[item.plot.valueField]) {
                  item.plot.valueField = map[item.plot.valueField].FieldName
                }
                if (item.plot.labelField && map[item.plot.labelField]) {
                  item.plot.labelField = map[item.plot.labelField].FieldName
                }
                // 饼图
                if (item.plot.type && map[item.plot.type]) {
                  item.plot.type = map[item.plot.type].FieldName
                }
                // 散点图
                if (item.plot.gender && map[item.plot.gender]) {
                  item.plot.gender = map[item.plot.gender].FieldName
                }
                if (item.Yaxis) {
                  if (Array.isArray(item.Yaxis)) {
                    item.Yaxis = item.Yaxis.map(m => {
                      if (map[m]) {
                        return map[m].FieldName
                      }
                      return m
                    })
                  } else {
                    if (map[item.Yaxis]) {
                      item.Yaxis = map[item.Yaxis].FieldName
                    }
                  }
                }
              }
              if (item.cols) {
                let _update = (cols) => {
                  return cols.map(col => {
                    if (col.type === 'action' && col.elements) {
                      col.elements = col.elements.map(m => {
                        if (m.modal && m.modal.fields) {
                          m.modal.fields = m.modal.fields.map(col => {
                            if (map[col.field]) {
                              col.field = map[col.field].FieldName
                            }
                            return col
                          })
                        }
                        return m
                      })
                    } else if (col.type === 'custom' && col.elements) {
                      col.elements = col.elements.map(m => {
                        if (m.datatype === 'dynamic' && map[m.field]) {
                          m.field = map[m.field].FieldName
                        }
                        return m
                      })
                    } else if (col.type === 'colspan') {
                      col.subcols = _update(col.subcols)
                    } else if (col.field) {
                      if (map[col.field]) {
                        col.field = map[col.field].FieldName
                      }
                    }
                    return col
                  })
                }
                item.cols = _update(item.cols)
              }
              return item
            })
          }
          config.components = _replace(config.components)
        }
        this.setState({
          confirming: false,
          visible: false
        })
        notification.success({
          top: 92,
          message: '更新已完成。',
          duration: 3
        })
        this.props.updateConfig(config)
      })
    })
  }
  render() {
    const { visible, loadingTable, tables, confirming } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        <Button className="mk-border-yellow" icon="swap" loading={loadingTable} onClick={this.trigger}>字段替换</Button>
        <Modal
          title="字段替换"
          wrapClassName="replace-field-modal"
          visible={visible}
          width={600}
          maskClosable={false}
          onOk={this.submit}
          onCancel={() => { this.setState({ visible: false })}}
          confirmLoading={confirming}
          destroyOnClose
        >
          <SettingForm tables={tables} wrappedComponentRef={(inst) => this.settingRef = inst}/>
        </Modal>
      </div>
    )
  }
}
export default ReplaceField
src/menu/replaceField/index.scss
New file
@@ -0,0 +1,9 @@
.replace-field-modal {
  .ant-modal {
    top: 70px;
  }
  .ant-modal-body {
    min-height: 150px;
    padding-top: 40px;
  }
}
src/menu/replaceField/settingform/index.jsx
New file
@@ -0,0 +1,78 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Tooltip, Icon, Select } from 'antd'
import './index.scss'
class SettingForm extends Component {
  static propTpyes = {
    tables: PropTypes.object
  }
  state = {}
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const { tables } = this.props
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      }
    }
    return (
      <Form {...formItemLayout}>
        <Row gutter={24}>
          <Col span={20}>
            <Form.Item label={
              <Tooltip placement="topLeft" title="用于字段替换的表名。">
                <Icon type="question-circle" style={{color: '#c49f47', marginRight: '3px'}} />
                表名
              </Tooltip>
            }>
              {getFieldDecorator('table', {
                initialValue: '',
                rules: [
                  {
                    required: true,
                    message: '请选择表名'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                >
                  {tables.map((option, i) =>
                    <Select.Option key={i} title={option.Remark + ' (' + option.TbName + ')'} value={option.TbName}>{option.Remark + ' (' + option.TbName + ')'}</Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        </Row>
      </Form>
    )
  }
}
export default Form.create()(SettingForm)
src/menu/replaceField/settingform/index.scss
src/views/interface/index.jsx
@@ -3,9 +3,6 @@
import enUS from 'antd/es/locale/en_US'
import zhCN from 'antd/es/locale/zh_CN'
// import Api from '@/views/interface/api'
// import asyncComponent from '@/utils/asyncComponent'
// import options from '@/store/options.js'
import Header from './header'
import History from './history'
import WorkSpace from './workspace'
@@ -15,11 +12,6 @@
const _locale = sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
class Interface extends Component {
  componentDidMount() {
    //
  }
  render () {
    return (
      <div className="interface-view">
src/views/menudesign/index.jsx
@@ -34,6 +34,7 @@
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const PaddingController = asyncComponent(() => import('@/menu/padcontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const PictureController = asyncComponent(() => import('@/menu/picturecontroller'))
@@ -899,6 +900,17 @@
    window.GLOB.customMenu = config
  }
  resetConfig = (config) => {
    this.setState({
      config: {...config, components: []}
    }, () => {
      this.setState({
        config: config
      })
    })
    window.GLOB.customMenu = config
  }
  insert = (item) => {
    let config = fromJS(this.state.config).toJS()
@@ -968,6 +980,7 @@
                  <div> {config && config.MenuName} </div>
                } bordered={false} extra={
                  <div>
                    <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
                    <SysInterface config={config} updateConfig={this.updateConfig}/>
                    <PictureController/>
                    <StyleCombControlButton menu={config} />
src/views/mobdesign/index.jsx
@@ -28,6 +28,7 @@
const CreateView = asyncComponent(() => import('@/pc/createview'))
const SourceWrap = asyncComponent(() => import('@/mob/modulesource'))
const BgController = asyncComponent(() => import('@/pc/bgcontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
const Quotecomponent = asyncComponent(() => import('@/pc/quotecomponent'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
@@ -1486,6 +1487,20 @@
    })
  }
  resetConfig = (config) => {
    this.setState({
      config: config,
      comloading: true
    }, () => {
      this.setState({
        comloading: false
      })
    })
    window.GLOB.customMenu = config
  }
  render () {
    const { localedict, comloading, loading, settingshow, controlshow, activeKey, dict, MenuId, config, menuloading, customComponents } = this.state
@@ -1543,6 +1558,7 @@
              <Quotecomponent config={config} updateConfig={this.updateConfig}/>
              <Button className="mk-border-green" icon="home" onClick={this.setHomeView}>设为首页</Button>
              <Button className="mk-border-danger" icon="redo" onClick={this.refreshView}>强制刷新</Button>
              <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
              <Button type="default" onClick={this.closeView}>关闭</Button>
            </div>
            <div className={'menu-body ' + (menuloading ? 'saving' : '')}>
src/views/pcdesign/index.jsx
@@ -30,6 +30,7 @@
const Quotecomponent = asyncComponent(() => import('@/pc/quotecomponent'))
const PasteController = asyncComponent(() => import('@/menu/pastecontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ReplaceField = asyncComponent(() => import('@/menu/replaceField'))
const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const PictureController = asyncComponent(() => import('@/menu/picturecontroller'))
@@ -1401,6 +1402,19 @@
    window.GLOB.customMenu = config
  }
  resetConfig = (config) => {
    this.setState({
      config: config,
      comloading: true
    }, () => {
      this.setState({
        comloading: false
      })
    })
    window.GLOB.customMenu = config
  }
  insert = (item) => {
    let config = fromJS(this.state.config).toJS()
@@ -1546,6 +1560,7 @@
              <Quotecomponent config={config} updateConfig={this.updateConfig}/>
              <Button className="mk-border-green" icon="home" onClick={this.setHomeView}>设为首页</Button>
              <Button className="mk-border-danger" icon="redo" onClick={this.refreshView}>强制刷新</Button>
              <ReplaceField type="custom" config={config} updateConfig={this.resetConfig}/>
              <Button type="default" onClick={this.closeView}>关闭</Button>
            </div>
            <div className={'menu-body ' + (menuloading ? 'saving' : '')}>