king
2023-10-24 6c18224399d626790d85b2081e42356eb23d9453
2023-10-24
6个文件已修改
4个文件已添加
600 ■■■■ 已修改文件
src/api/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/colsControl/index.jsx 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/colsControl/index.scss 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/colsControl/markform/index.jsx 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/colsControl/markform/index.scss 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/markcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/markcomponent/index.scss 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -1099,7 +1099,7 @@
        clearTimeout(timer)
        if (/Shared Memory Provider|会话处于终止状态|当前命令发生了严重错误/.test(res.message)) {
          res.message = '验证失败,请检查SQL中是否存在死循环。'
        } else if (res.message === 'ROLLBACK TRANSACTION 请求没有对应的 BEGIN TRANSACTION。 EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。 ROLLBACK TRANSACTION 请求没有对应的 BEGIN TRANSACTION。') {
        } else if (res.message.indexOf('EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0') > -1) {
          res.ErrCode = '-2'
        }
        resolve(res)
src/menu/components/share/colsControl/index.jsx
New file
@@ -0,0 +1,299 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Modal, notification, Popconfirm } from 'antd'
import { ApartmentOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import MarkForm from './markform'
import './index.scss'
const EditTable = asyncComponent(() => import('@/templates/zshare/editTable'))
const { confirm } = Modal
class ColsControl extends Component {
  static propTpyes = {
    config: PropTypes.object,
    onSubmit: PropTypes.func
  }
  state = {
    searches: [],
    visible: false,
    colsCtrls: [],
    cols: [],
    svalues: {},
    cvalues: {},
    columns: [
      {
        title: '字段',
        dataIndex: 'field',
        width: '18%'
      },
      {
        title: '对比方式',
        dataIndex: 'match',
        width: '18%',
      },
      {
        title: '对比值',
        dataIndex: 'contrastValue',
        width: '18%',
      },
      {
        title: '显示列',
        dataIndex: 'cols',
        width: '24%',
        render: text => {
          return text.length
        }
      },
      {
        title: '操作',
        align: 'center',
        width: '18%',
        dataIndex: 'operation',
        render: (text, record) =>
          (<div style={{textAlign: 'center', cursor: 'default'}}>
            <span title="编辑" onClick={() => this.handleEdit(record)} style={{color: '#1890ff', marginRight: '15px', cursor: 'pointer'}}><EditOutlined /></span>
            <Popconfirm
              overlayClassName="popover-confirm"
              title="确定删除吗?"
              onConfirm={() => this.handleDelete(record)
            }>
              <span style={{color: '#ff4d4f', cursor: 'pointer'}}><DeleteOutlined /></span>
            </Popconfirm>
          </div>)
      }
    ]
  }
  handleEdit = (record) => {
    this.customForm.edit(record)
  }
  markChange = (values) => {
    let colsCtrls = fromJS(this.state.colsCtrls).toJS()
    let has = false
    if (!values.uuid) {
      colsCtrls.forEach(item => {
        if (item.field.join('') === values.field.join('') && item.match === values.match && item.contrastValue === values.contrastValue) {
          has = true
        }
      })
      values.uuid = Utils.getuuid()
      colsCtrls.push(values)
    } else {
      colsCtrls = colsCtrls.map(item => {
        if (values.uuid === item.uuid) {
          return values
        }
        if (item.field.join('') === values.field.join('') && item.match === values.match && item.contrastValue === values.contrastValue) {
          has = true
        }
        return item
      })
    }
    if (has) {
      notification.warning({
        top: 92,
        message: '此设置已存在!',
        duration: 5
      })
      return
    }
    this.setState({
      colsCtrls: colsCtrls
    })
  }
  handleDelete = (record) => {
    const { colsCtrls } = this.state
    this.setState({ colsCtrls: colsCtrls.filter(item => item.uuid !== record.uuid) })
  }
  resetMark = () => {
    const { config } = this.props
    const { columns } = this.state
    let search = config.search || []
    if (config.setting.useMSearch === 'true') { // 使用主搜索条件
      let menu = fromJS(window.GLOB.customMenu).toJS()
      let filterComponent = (box, mainSearch) => {
        box.components.forEach(item => {
          if (item.type !== 'search') return
          mainSearch = item.search
        })
        let has = false
        box.components.forEach(item => {
          if (item.uuid === config.uuid) {
            has = true
          } else if (item.type === 'group') {
            item.components.forEach(m => {
              if (m.uuid !== config.uuid) return
              has = true
            })
          }
        })
        if (has) {
          search = [...search, ...(mainSearch || [])]
        } else {
          box.components.forEach(item => {
            if (item.type !== 'tabs') return
            item.subtabs.forEach(tab => {
              filterComponent(tab, mainSearch)
            })
          })
        }
      }
      filterComponent(menu, null)
    }
    let cvalues = {}
    let cols = config.cols.map(item => {
      let types = {custom: '自定义列', colspan: '合并列'}
      let label = types[item.type] ? `${item.label}(${types[item.type]})` : item.label
      cvalues[item.uuid] = label
      return {
        key: item.uuid,
        title: label
      }
    })
    let searches = [{value: 'BID', label: 'BID'}]
    let svalues = {BID: 'BID'}
    search.forEach(item => {
      if (!item.field || item.type === 'group') return
      svalues[item.field] = item.label
      searches.push({value: item.field, label: item.label})
    })
    let colsCtrls = fromJS(config.colsCtrls || []).toJS()
    colsCtrls = colsCtrls.map(col => {
      col.cols = col.cols.filter(f => !!cvalues[f])
      return col
    })
    this.setState({
      cols,
      svalues,
      columns: columns.map(col => {
        if (col.dataIndex === 'field') {
          col.render = (text) => {
            return text.map(cell => svalues[cell] || cell).join('、')
          }
        } else if (col.dataIndex === 'cols') {
          col.render = (text) => {
            return text.map(cell => cvalues[cell] || cell).join('、')
          }
        }
        return col
      }),
      visible: true,
      searches: searches,
      colsCtrls: colsCtrls
    })
  }
  markSubmit = () => {
    const { config } = this.props
    const { colsCtrls, svalues } = this.state
    let _config = fromJS(config).toJS()
    let s = []
    let c = []
    colsCtrls.forEach((col, index) => {
      if (col.field.findIndex(f => !svalues[f]) > -1) {
        s.push(index + 1)
      }
      if (col.cols.length === 0) {
        c.push(index + 1)
      }
    })
    if (c.length > 0) {
      Modal.warning({
        title: `第 ${c.join('、')} 行中显示列不可为空。`,
        okText: '知道了'
      })
      return
    }
    _config.colsCtrls = colsCtrls
    if (this.customForm && this.customForm.state.editItem) {
      const _this = this
      let title = '存在未保存项,确定忽略吗?'
      if (s.length > 0) {
        title = `存在未保存项,且第 ${s.join('、')} 行中字段在搜索条件中不存在,确定忽略吗?`
      }
      confirm({
        title: title,
        onOk() {
          _this.setState({ visible: false })
          _this.props.onSubmit(_config)
        },
        onCancel() {}
      })
    } else if (s.length > 0) {
      const _this = this
      confirm({
        title: `第 ${s.join('、')} 行中字段在搜索条件中不存在,确定忽略吗?`,
        onOk() {
          _this.setState({ visible: false })
          _this.props.onSubmit(_config)
        },
        onCancel() {}
      })
    } else {
      this.setState({
        visible: false
      })
      this.props.onSubmit(_config)
    }
  }
  render() {
    const { colsCtrls, columns, visible, cols, searches } = this.state
    return (
      <div style={{display: 'inline-block'}}>
        <ApartmentOutlined style={{color: '#13c2c2'}} title="显示列控制" onClick={this.resetMark} />
        <Modal
          wrapClassName="column-control-modal-wrap"
          title="显示列控制"
          visible={visible}
          width={'75vw'}
          maskClosable={false}
          okText="提交"
          onOk={this.markSubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          <MarkForm columns={cols} searches={searches} markChange={this.markChange} wrappedComponentRef={(inst) => this.customForm = inst}/>
          <EditTable actions={['edit', 'move', 'del']} data={colsCtrls} columns={columns} onChange={(colsCtrls) => this.setState({colsCtrls})}/>
        </Modal>
      </div>
    )
  }
}
export default ColsControl
src/menu/components/share/colsControl/index.scss
New file
@@ -0,0 +1,30 @@
.column-control-modal-wrap {
  .ant-modal {
    top: 50px;
    padding-bottom: 5px;
    .ant-modal-body {
      max-height: calc(100vh - 190px);
      min-height: 350px;
      overflow-y: auto;
      padding-bottom: 50px;
      .msg {
        margin-bottom: 10px;
      }
    }
    .ant-modal-body::-webkit-scrollbar {
      width: 7px;
    }
    .ant-modal-body::-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-modal-body::-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);
    }
  }
}
src/menu/components/share/colsControl/markform/index.jsx
New file
@@ -0,0 +1,144 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Select, Button, Input, Transfer } from 'antd'
import './index.scss'
class ColsCtrlForm extends Component {
  static propTpyes = {
    columns: PropTypes.array,
    markChange: PropTypes.func
  }
  state = {
    targetKeys: [],
    editItem: null
  }
  edit = (item) => {
    this.setState({editItem: item, targetKeys: item.cols})
    this.props.form.setFieldsValue({
      field: item.field,
      match: item.match,
      contrastValue: item.contrastValue,
      cols: item.cols
    })
  }
  handleConfirm = () => {
    const { editItem } = this.state
    // 表单提交时检查输入值是否正确
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        if (editItem) {
          values.uuid = editItem.uuid
        }
        this.props.markChange(values)
        this.setState({targetKeys: null}, () => {
          this.setState({editItem: null, targetKeys: []})
        })
      }
    })
  }
  handleCancel = () => {
    this.setState({targetKeys: null}, () => {
      this.setState({editItem: null, targetKeys: []})
    })
  }
  handleChange = (newTargetKeys) => {
    this.setState({targetKeys: newTargetKeys})
  }
  render() {
    const { columns, searches } = this.props
    const { getFieldDecorator } = this.props.form
    const { targetKeys, editItem } = this.state
    return (
      <Form className="normal-table-cols-form">
        <Row gutter={24}>
          <Col span={6}>
            <Form.Item label="字段">
              {getFieldDecorator('field', {
                initialValue: [],
                rules: [
                  {
                    required: true,
                    message: '请选择字段!'
                  }
                ]
              })(
                <Select mode="multiple">
                  {searches.map((item, i) => (<Select.Option key={i} value={item.value}> {item.label} </Select.Option>))}
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={6}>
            <Form.Item label="对比方式">
              {getFieldDecorator('match', {
                initialValue: '=',
                rules: [
                  {
                    required: true,
                    message: '请选择对比方式!'
                  }
                ]
              })(
                <Select>
                  <Select.Option value="="> = </Select.Option>
                  <Select.Option value="!="> != </Select.Option>
                  <Select.Option value=">"> &gt; </Select.Option>
                  <Select.Option value="<"> &lt; </Select.Option>
                </Select>
              )}
            </Form.Item>
          </Col>
          <Col span={6}>
            <Form.Item label="对比值">
              {getFieldDecorator('contrastValue', {
                initialValue: ''
              })(<Input placeholder="" autoComplete="off" />)}
            </Form.Item>
          </Col>
          <Col span={6} style={{padding: '5px 0px 0px 30px'}}>
            <Button onClick={this.handleConfirm} type="primary" className="mk-green">
              {editItem ? '保存' : '添加'}
            </Button>
            {editItem ? <Button style={{marginLeft: '15px'}} onClick={this.handleCancel}>
              取消
            </Button> : null}
          </Col>
          {targetKeys ? <Col span={18}>
            <Form.Item label="显示列">
              {getFieldDecorator('cols', {
                initialValue: [],
                rules: [
                  {
                    required: true,
                    message: '请选择显示列!'
                  }
                ]
              })(
                <Transfer
                  targetKeys={targetKeys}
                  dataSource={columns}
                  render={item => item.title}
                  onChange={this.handleChange}
                />
              )}
            </Form.Item>
          </Col> : null}
        </Row>
      </Form>
    )
  }
}
export default Form.create()(ColsCtrlForm)
src/menu/components/share/colsControl/markform/index.scss
New file
@@ -0,0 +1,18 @@
.normal-table-cols-form {
  .ant-form-item {
    display: flex;
    .ant-form-item-label {
      width: 80px;
    }
    .ant-form-item-control-wrapper {
      flex: 10;
      .ant-transfer {
        .ant-transfer-list {
          width: calc(50% - 20px);
          height: 250px;
        }
      }
    }
  }
}
src/menu/components/share/markcomponent/index.jsx
@@ -418,7 +418,7 @@
      <div style={{display: 'inline-block'}}>
        <AntDesignOutlined className="profile" title="标记" onClick={this.resetMark} />
        <Modal
          wrapClassName="model-table-column-mark-modal"
          wrapClassName="mark-modal-wrap"
          title="标记设置"
          visible={visible}
          width={'75vw'}
src/menu/components/share/markcomponent/index.scss
@@ -1,59 +1,25 @@
#mark-column-box-modal {
  table tr td {
    word-wrap: break-word;
    word-break: break-word;
  }
  .mingke-table .ant-empty {
    margin: 20px 8px!important;
  }
  .mingke-table {
    td {
      position: relative;
.mark-modal-wrap {
  .ant-modal {
    top: 50px;
    padding-bottom: 5px;
    .ant-modal-body {
      max-height: calc(100vh - 190px);
      min-height: 350px;
      overflow-y: auto;
    }
  }
  .errorval {
    display: inline-block;
    width: 30px;
  }
  .operation-btn {
    display: inline-block;
    font-size: 16px;
    padding: 0 5px;
    cursor: pointer;
  }
  .ant-tabs-tabpane {
    position: relative;
    .excel-col-add {
      position: absolute;
      right: 0;
      top: 90px;
    .ant-modal-body::-webkit-scrollbar {
      width: 7px;
    }
  }
  .ant-table-tbody tr.background td {
    background: unset!important;
  }
  .background {
    .baseboard {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    .ant-modal-body::-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);
    }
    .content {
      position: relative;
    .ant-modal-body::-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);
    }
  }
  .mk-table-line.background {
    .baseboard {
      background: unset!important;
    }
  }
  .ant-form-item {
    white-space: nowrap;
  }
}
src/menu/components/table/edit-table/columns/index.jsx
@@ -16,6 +16,7 @@
const EditColumn = asyncComponent(() => import('./editColumn'))
const TableVerify = asyncComponent(() => import('./tableIn'))
const MarkColumn = asyncIconComponent(() => import('@/menu/components/share/markcomponent'))
const ColsControl = asyncIconComponent(() => import('@/menu/components/share/colsControl'))
const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent'))
const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
@@ -249,13 +250,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    const { config } = this.props
    return !is(fromJS(this.state), fromJS(nextState)) ||
      !is(fromJS(config.wrap), fromJS(nextProps.config.wrap)) ||
      !is(fromJS(config.submit), fromJS(nextProps.config.submit)) ||
      !is(fromJS(config.action), fromJS(nextProps.config.action)) ||
      config.setting.laypage !== nextProps.config.setting.laypage
    return !is(fromJS(this.state), fromJS(nextState)) || !is(fromJS(this.props.config), fromJS(nextProps.config))
  }
  moveCol = (dragIndex, hoverIndex) => {
@@ -696,6 +691,7 @@
          </Popover>
          <CopyOutlined title="复制显示列" onClick={this.copycolumn} />
          <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} />
          <ColsControl config={config} onSubmit={this.props.updatecolumn}/>
          <FileSyncOutlined title="同步字段集" onClick={this.syncfield} />
          <DeleteOutlined title="清空显示列" onClick={this.clear}/>
        </div>
src/menu/components/table/normal-table/columns/index.jsx
@@ -17,6 +17,7 @@
const MarkColumn = asyncIconComponent(() => import('@/menu/components/share/markcomponent'))
const CardCellComponent = asyncComponent(() => import('@/menu/components/card/cardcellcomponent'))
const MobPagination = asyncIconComponent(() => import('@/menu/components/share/mobPagination'))
const ColsControl = asyncIconComponent(() => import('@/menu/components/share/colsControl'))
const PasteComponent = asyncIconComponent(() => import('@/components/paste'))
class HeaderCol extends Component {
@@ -277,12 +278,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    const { config } = this.props
    return !is(fromJS(this.state), fromJS(nextState)) ||
      !is(fromJS(config.wrap), fromJS(nextProps.config.wrap)) ||
      !is(fromJS(config.action), fromJS(nextProps.config.action)) ||
      config.setting.laypage !== nextProps.config.setting.laypage
    return !is(fromJS(this.state), fromJS(nextState)) || !is(fromJS(this.props.config), fromJS(nextProps.config))
  }
  moveCol = (dragIndex, hoverIndex) => {
@@ -659,6 +655,7 @@
          <PlusOutlined style={{color: '#26C281'}} title="添加列" onClick={this.addColumns}/>
          <CopyOutlined title="复制显示列" onClick={this.copycolumn} />
          <MarkColumn columns={fields} type="line" marks={lineMarks} onSubmit={this.updateLineMarks} />
          <ColsControl config={config} onSubmit={this.props.updatecolumn}/>
          <FileSyncOutlined title="同步字段集" onClick={this.syncfield} />
          <DeleteOutlined title="清空显示列" onClick={this.clear}/>
        </div>
src/utils/utils-custom.js
@@ -558,6 +558,13 @@
        }
        item.cols = loopCol(item.cols)
        if (item.colsCtrls) {
          item.colsCtrls = item.colsCtrls.map(col => {
            col.cols = col.cols.map(f => md5(commonId + f))
            return col
          })
        }
      } else if (item.type === 'form') {
        item.subcards = item.subcards.map(cell => {
          cell.uuid = this.getuuid()
@@ -851,6 +858,13 @@
      }
      item.cols = loopCol(item.cols)
      if (item.colsCtrls) {
        item.colsCtrls = item.colsCtrls.map(col => {
          col.cols = col.cols.map(f => md5(commonId + f))
          return col
        })
      }
    } else if (item.type === 'form') {
      item.subcards = item.subcards.map(cell => {
        cell.uuid = this.getuuid()