king
2021-03-28 8a0b3081ecacbb844ea639ccc53ffd2c151cec1e
2021-03-28
29个文件已修改
4个文件已添加
612 ■■■■ 已修改文件
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/index.jsx 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/utils.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/urlfieldcomponent/index.jsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/urlfieldcomponent/index.scss 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/urlfieldcomponent/settingform/index.jsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/urlfieldcomponent/settingform/index.scss 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/calendar/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/data-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/prop-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/data-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/carousel/prop-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-bar-line/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/chart/antv-pie/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/treepage/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/tabbutton/index.jsx 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.jsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/calendarconfig/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/columnform/index.jsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/utils.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-datamanage.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/menuform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -50,6 +50,10 @@
    })
  }
  if (!card.linkurl && (!card.linkmenu || card.linkmenu.length === 0)) {
    card.perspective = ''
  }
  return [
    {
      type: 'text',
@@ -295,8 +299,11 @@
      type: 'radio',
      key: 'perspective',
      label: '字段透视',
      initVal: card.perspective || 'linkmenu',
      initVal: card.perspective || '',
      options: [{
        value: '',
        text: '无'
      }, {
        value: 'linkmenu',
        text: '菜单'
      }, {
@@ -309,7 +316,7 @@
      key: 'linkmenu',
      label: Formdict['model.menu'],
      initVal: card.linkmenu || [],
      required: false,
      required: true,
      options: menulist
    },
    {
@@ -317,7 +324,15 @@
      key: 'linkurl',
      label: '链接地址',
      initVal: card.linkurl || '',
      required: false
      required: true
    },
    {
      type: 'multiselect',
      key: 'linkfields',
      label: '关联字段',
      initVal: card.linkfields || [],
      required: false,
      options: fields
    },
    {
      type: 'multiselect',
src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -54,9 +54,9 @@
    let formlist = getColumnForm(column, menulist, this.props.fields)
    let _options = fromJS(columnTypeOptions[column.type]).toJS()
    if (column.type === 'text' || column.type === 'number') {
      if (column.perspective !== 'linkurl') {
        _options.push('linkmenu')
      } else {
      if (column.perspective === 'linkmenu') {
        _options.push('linkmenu', 'linkfields')
      } else if (column.perspective === 'linkurl') {
        _options.push('linkurl')
      }
    }
@@ -85,10 +85,6 @@
    if (key === 'type') {
      let _options = fromJS(columnTypeOptions[value]).toJS()
      if (value === 'text' || value === 'number') {
        _options.push('linkmenu')
      }
      this.setState({
        type: value,
        formlist: this.state.formlist.map(item => {
@@ -100,7 +96,7 @@
        if (value === 'link' || value === 'textarea' || value === 'picture') {
          this.props.form.setFieldsValue({IsSort: 'false'})
        } else if (value === 'text' || value === 'number') {
          this.props.form.setFieldsValue({perspective: 'linkmenu'})
          this.props.form.setFieldsValue({perspective: ''})
        } else if (value === 'action' || value === 'colspan') {
          this.props.form.setFieldsValue({Align: 'center'})
        }
@@ -123,9 +119,9 @@
    if (key === 'perspective') {
      let _options = fromJS(columnTypeOptions[this.state.type]).toJS()
      if (value !== 'linkurl') {
        _options.push('linkmenu')
      } else {
      if (value === 'linkmenu') {
        _options.push('linkmenu', 'linkfields')
      } else if (value === 'linkurl') {
        _options.push('linkurl')
      }
@@ -273,7 +269,7 @@
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                >
                  {item.options.map((option, i) =>
                    <Select.Option id={i} key={i} value={option.value}>{option.text}</Select.Option>
                    <Select.Option id={i} key={i} value={option.value || option.field}>{option.text || option.label}</Select.Option>
                  )}
                </Select>
              )}
@@ -285,7 +281,13 @@
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || []
                initialValue: item.initVal || [],
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Cascader
                  options={item.options}
src/menu/datasource/verifycard/utils.jsx
@@ -40,6 +40,15 @@
      _dataresource = _dataresource.replace(/@db@/ig, window.GLOB.externalDatabase)
      _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase)
    }
    if (window.GLOB.urlFields) {
      window.GLOB.urlFields.forEach(field => {
        let reg = new RegExp('@' + field + '@', 'ig')
        _dataresource = _dataresource.replace(reg, '0')
        _customScript = _customScript.replace(reg, '0')
      })
    }
    
    // 正则替换
    let _regoptions = []
src/menu/urlfieldcomponent/index.jsx
New file
@@ -0,0 +1,135 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Icon, Modal, Tooltip, notification } from 'antd'
import SettingForm from './settingform'
import './index.scss'
const { confirm } = Modal
class UrlFieldComponent extends Component {
  static propTpyes = {
    config: PropTypes.any,
    updateConfig: PropTypes.func
  }
  state = {
    visible: false,
    urlFields: this.props.config.urlFields || []
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  editDataSource = () => {
    this.setState({
      visible: true
    })
  }
  verifySubmit = () => {
    const { urlFields } = this.state
    const { config } = this.props
    this.verifyRef.handleConfirm().then(res => {
      if (urlFields.filter(field => field === res.field).length > 0) {
        notification.warning({
          top: 92,
          message: '字段已存在!',
          duration: 5
        })
        return
      }
      let _urlFields = [...urlFields, res.field]
      this.setState({
        visible: false,
        urlFields: _urlFields
      })
      if (window.GLOB.urlFields) {
        window.GLOB.urlFields = _urlFields
      }
      this.props.updateConfig({...config, urlFields: _urlFields})
    })
  }
  deleteField = (field) => {
    let config = JSON.stringify(this.props.config)
    const _this = this
    if (new RegExp(field, 'ig').test(config)) {
      confirm({
        title: `配置中存在@${field}@,确定删除吗?`,
        content: '',
        onOk() {
          _this.execDelete(field)
        },
        onCancel() {}
      })
    } else {
      this.execDelete(field)
    }
  }
  execDelete = (_field) => {
    const { config } = this.props
    let _urlFields = this.state.urlFields.filter(field => field !== _field)
    this.setState({
      urlFields: _urlFields
    })
    if (window.GLOB.urlFields) {
      window.GLOB.urlFields = _urlFields
    }
    this.props.updateConfig({...config, urlFields: _urlFields})
  }
  render () {
    const { visible, urlFields } = this.state
    return (
      <div className="url-field-component">
        <div className="field-plus">
          <Tooltip placement="topLeft" title="页面可接收的参数字段,在查询数据源或自定义脚本中使用 @字段@ 接收。">
            <Icon type="question-circle" />
            url变量
          </Tooltip>
          <Icon type="plus" title="添加" onClick={() => this.editDataSource()} />
        </div>
        <div>
          {urlFields.map((field, index) => {
            return (
              <div className="field-item" key={index}>
                <Icon type="close" title="删除" onClick={() => this.deleteField(field)} />
                {field}
              </div>
            )
          })}
        </div>
        <Modal
          title="字段添加"
          visible={visible}
          width={500}
          maskClosable={false}
          onOk={this.verifySubmit}
          onCancel={() => { this.setState({ visible: false }) }}
          destroyOnClose
        >
          <SettingForm
            inputSubmit={this.verifySubmit}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
          />
        </Modal>
      </div>
    )
  }
}
export default UrlFieldComponent
src/menu/urlfieldcomponent/index.scss
New file
@@ -0,0 +1,28 @@
.url-field-component {
  margin-bottom: 15px;
  .field-plus {
    line-height: 35px;
    >.anticon-plus {
      color: #26C281;
      padding: 2px 5px;
      margin-left: 5px;
    }
    .anticon-question-circle {
      color: #c49f47;
      margin-right: 3px;
    }
  }
  .field-item {
    position: relative;
    border: 1px solid #e8e8e8;
    padding: 5px 10px;
    border-radius: 4px;
    >.anticon-close {
      position: absolute;
      right: 5px;
      top: 3px;
      font-size: 13px;
    }
  }
}
src/menu/urlfieldcomponent/settingform/index.jsx
New file
@@ -0,0 +1,71 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Input } from 'antd'
import './index.scss'
class SettingForm extends Component {
  static propTpyes = {
    inputSubmit: PropTypes.func  // 回车事件
  }
  handleConfirm = () => {
    // 表单提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  handleSubmit = (e) => {
    e.preventDefault()
    if (this.props.inputSubmit) {
      this.props.inputSubmit()
    }
  }
  render() {
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 14 }
      }
    }
    return (
      <div className="url-field-form">
        <Form {...formItemLayout}>
          <Form.Item label="字段名">
            {getFieldDecorator('field', {
              initialValue: '',
              rules: [
                {
                  required: true,
                  message: '请输入字段名!'
                },
                {
                  pattern: /^[a-zA-Z0-9_]*$/ig,
                  message: '字段可使用英文、数字或_'
                }
              ]
            })(<Input placeholder={''} autoComplete="off" onPressEnter={this.handleSubmit} />)}
          </Form.Item>
        </Form>
      </div>
    )
  }
}
export default Form.create()(SettingForm)
src/menu/urlfieldcomponent/settingform/index.scss
src/tabviews/calendar/index.jsx
@@ -124,12 +124,8 @@
      let roleId = sessionStorage.getItem('role_id') || ''
      config.search = config.search.map(item => {
        item.oriInitval = item.initval
        if (['text', 'select', 'link'].includes(item.type) && param) {
          if (param.searchkey === item.field) {
            item.initval = param.searchval
          } else if (param.data && param.data[item.field]) {
            item.initval = param.data[item.field]
          }
        if (['text', 'select', 'link'].includes(item.type) && param && param.$searchkey === item.field) {
          item.initval = param.$searchval
        }
        if (item.required === 'true' && !item.initval) {
@@ -173,12 +169,21 @@
          config.setting.dataresource = config.setting.dataresource.replace(/@\$|\$@/ig, '')
          _customScript = _customScript.replace(/@\$|\$@/ig, '')
        }
        if (config.urlFields) {
          let _param = param || {}
          config.urlFields.forEach(field => {
            let reg = new RegExp('@' + field + '@', 'ig')
            let val = `'${_param[field] || ''}'`
            config.setting.dataresource = config.setting.dataresource.replace(reg, val)
            _customScript = _customScript.replace(reg, val)
          })
        }
        config.setting.customScript = _customScript
      }
      this.setState({
        BID: param && param.BID ? param.BID : '',
        BID: param && param.$BID ? param.$BID : '',
        loadingview: false,
        config: config,
        userConfig: userConfig,
@@ -462,18 +467,6 @@
  UNSAFE_componentWillMount () {
    // 组件加载时,获取菜单数据
    this.loadconfig()
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps.param && !is(fromJS(this.props.param), fromJS(nextProps.param))) {
      let search = this.state.search.map(item => {
        if (item.type === 'text' && item.key === nextProps.param.searchkey) {
          item.value = nextProps.param.searchval
        }
        return item
      })
      this.refreshbysearch(search)
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
src/tabviews/commontable/index.jsx
@@ -179,12 +179,8 @@
      // 字段权限黑名单
      config.search = config.search.map(item => {
        item.oriInitval = item.initval
        if (['text', 'select', 'link'].includes(item.type) && param) {
          if (param.searchkey === item.field) {
            item.initval = param.searchval
          } else if (param.data && param.data[item.field]) {
            item.initval = param.data[item.field]
          }
        if (['text', 'select', 'link'].includes(item.type) && param && param.$searchkey === item.field) {
          item.initval = param.$searchval
        }
        if (!item.blacklist || item.blacklist.length === 0) return item
@@ -211,6 +207,7 @@
      config.setting.laypage = config.setting.laypage !== 'false'     // 是否分页,转为boolean 统一格式
      config.setting.execute = config.setting.default !== 'false'     // 默认sql是否执行,转为boolean 统一格式
      config.setting.customScript = ''                                // 自定义脚本
      config.setting.dataresource = config.setting.dataresource || ''
      if (config.setting.interType === 'system' || (config.setting.interType === 'custom' && config.setting.requestMode === 'system')) {
        if (config.setting.scripts && config.setting.scripts.length > 0) {
@@ -226,8 +223,6 @@
  
        if (!config.setting.execute) { // 默认sql 不执行时 置空
          config.setting.dataresource = ''
        } else {
          config.setting.dataresource = config.setting.dataresource || ''
        }
        if (/\s/.test(config.setting.dataresource)) {
          config.setting.dataresource = '(' + config.setting.dataresource + ') tb'
@@ -241,6 +236,15 @@
        } else {
          config.setting.dataresource = config.setting.dataresource.replace(/@\$|\$@/ig, '')
          config.setting.customScript = config.setting.customScript.replace(/@\$|\$@/ig, '')
        }
        if (config.urlFields) {
          let _param = param || {}
          config.urlFields.forEach(field => {
            let reg = new RegExp('@' + field + '@', 'ig')
            let val = `'${_param[field] || ''}'`
            config.setting.dataresource = config.setting.dataresource.replace(reg, val)
            config.setting.customScript = config.setting.customScript.replace(reg, val)
          })
        }
      }
@@ -361,7 +365,7 @@
        actions: _actions,
        columns: _columns,
        arr_field: _arrField.join(','),
        BID: param && param.BID ? param.BID : '',
        BID: param && param.$BID ? param.$BID : '',
        search: Utils.initMainSearch(config.search), // 搜索条件初始化(含有时间格式,需要转化)
        hasReqFields
      }, () => {
@@ -997,14 +1001,6 @@
      if (selectTab && selectTab.MenuID === this.props.MenuID) {
        this.setShortcut()
      }
    } else if (nextProps.param && !is(fromJS(this.props.param), fromJS(nextProps.param))) {
      let search = this.state.search.map(item => {
        if (item.type === 'text' && item.key === nextProps.param.searchkey) {
          item.value = nextProps.param.searchval
        }
        return item
      })
      this.refreshbysearch(search)
    }
  }
src/tabviews/custom/components/card/data-card/index.jsx
@@ -463,7 +463,7 @@
      }
      if (card.setting.joint === 'true') {
        newtab.param.BID = item.$$uuid
        newtab.param.$BID = item.$$uuid
      }
      if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) {
src/tabviews/custom/components/card/prop-card/index.jsx
@@ -362,7 +362,7 @@
      }
      if (item.setting.joint === 'true') {
        newtab.param.BID = item.setting.primaryId
        newtab.param.$BID = item.setting.primaryId || ''
      }
      if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) {
src/tabviews/custom/components/carousel/data-card/index.jsx
@@ -261,7 +261,7 @@
      }
      if (card.setting.joint === 'true') {
        newtab.param.BID = item.$$uuid
        newtab.param.$BID = item.$$uuid
      }
      if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) {
src/tabviews/custom/components/carousel/prop-card/index.jsx
@@ -267,7 +267,7 @@
      }
      if (item.setting.joint === 'true') {
        newtab.param.BID = item.setting.primaryId
        newtab.param.$BID = item.setting.primaryId
      }
      if (['linkage_navigation', 'linkage'].includes(window.GLOB.navBar)) {
src/tabviews/custom/components/chart/antv-bar-line/index.jsx
@@ -1350,8 +1350,7 @@
            ...menu,
            selected: true,
            param: {
              BID: primaryId,
              data: data
              $BID: primaryId
            }
          }
  
src/tabviews/custom/components/chart/antv-pie/index.jsx
@@ -602,8 +602,7 @@
            ...menu,
            selected: true,
            param: {
              BID: primaryId,
              data: data
              $BID: primaryId
            }
          }
  
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -511,9 +511,15 @@
      let tabmenu = item.linkThdMenu
      tabmenu.param = {
        searchkey: item.field,
        searchval: record[item.field] || '',
        BID: record.$$uuid
        $searchkey: item.field,
        $searchval: record[item.field] || '',
        $BID: record.$$uuid
      }
      if (item.linkfields && item.linkfields.length > 0) {
        item.linkfields.forEach(field => {
          tabmenu.param[field] = record[field] || ''
        })
      }
  
      tabmenu.selected = true
@@ -539,8 +545,8 @@
          let _url = item.linkurl.split('paramsmain/')[0] + 'paramsmain/'
          let _param = JSON.parse(window.decodeURIComponent(window.atob(item.linkurl.split('paramsmain/')[1])))
          let dataparam = {
            searchkey: item.field,
            searchval: record[item.field] || '',
            $searchkey: item.field,
            $searchval: record[item.field] || '',
            BID: record.$$uuid
          }
          _param.UserID = sessionStorage.getItem('UserID')
src/tabviews/custom/index.jsx
@@ -137,12 +137,8 @@
        component.search = component.search.map(item => {
          item.oriInitval = item.initval
          if (['text', 'select', 'link'].includes(item.type) && param) {
            if (param.searchkey === item.field) {
              item.initval = param.searchval
            } else if (param.data && param.data[item.field]) {
              item.initval = param.data[item.field]
            }
          if (['text', 'select', 'link'].includes(item.type) && param && param.$searchkey === item.field) {
            item.initval = param.$searchval
          }
          return item
@@ -152,7 +148,7 @@
      })
      let params = []
      let BID = param && param.BID ? param.BID : ''
      let BID = param && param.$BID ? param.$BID : ''
      let inherit = {}
      if (config.cacheUseful === 'true') { // 缓存继承
@@ -161,7 +157,25 @@
        inherit.cacheTime = config.cacheTime
      }
      config.components = this.formatSetting(config.components, params, mainSearch, inherit)
      let regs = []
      if (window.GLOB.externalDatabase !== null) {
        regs.push({
          reg: /@db@/ig,
          value: window.GLOB.externalDatabase
        })
      }
      if (config.urlFields) {
        config.urlFields.forEach(field => {
          let val = `'${param ? (param[field] || '') : ''}'`
          regs.push({
            reg: new RegExp(field, 'ig'),
            value: val
          })
        })
      }
      config.components = this.formatSetting(config.components, params, mainSearch, inherit, regs)
      this.setState({
        BID: BID,
@@ -655,17 +669,17 @@
  }
  // 格式化默认设置
  formatSetting = (components, params, mainSearch, inherit) => {
  formatSetting = (components, params, mainSearch, inherit, regs) => {
    return components.map(component => {
      if (component.type === 'tabs') {
        component.subtabs = component.subtabs.map(tab => {
          tab.components = this.formatSetting(tab.components, [], [], inherit)
          tab.components = this.formatSetting(tab.components, [], [], inherit, regs)
          tab = {...tab, ...inherit}
          return tab
        })
        return component
      } else if (component.type === 'group') {
        component.components = this.formatSetting(component.components, [], [], inherit)
        component.components = this.formatSetting(component.components, [], [], inherit, regs)
        component = {...component, ...inherit}
        return component
      }
@@ -712,11 +726,10 @@
        _customScript = _customScript.replace(/@\$|\$@/ig, '')
      }
      // 外联数据库替换
      if (window.GLOB.externalDatabase !== null) {
        component.setting.dataresource = component.setting.dataresource.replace(/@db@/ig, window.GLOB.externalDatabase)
        _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase)
      }
      regs.forEach(cell => {
        component.setting.dataresource = component.setting.dataresource.replace(cell.reg, cell.value)
        _customScript = _customScript.replace(cell.reg, cell.value)
      })
      component.setting.customScript = _customScript // 整理后自定义脚本
src/tabviews/treepage/index.jsx
@@ -174,7 +174,7 @@
      }
      this.setState({
        BID: param && param.BID ? param.BID : '',
        BID: param && param.$BID ? param.$BID : '',
        loadingview: false,
        config: config,
        setting: config.setting,
src/tabviews/zshare/actionList/tabbutton/index.jsx
@@ -73,11 +73,9 @@
    }
    let primaryId = ''
    let _data = null
    if (btn.Ot === 'requiredSgl') {
      primaryId = data[0][setting.primaryKey] || ''
      _data = data[0]
    }
    let newtab = {}
@@ -117,8 +115,7 @@
        ...menu,
        selected: true,
        param: {
          BID: primaryId,
          data: _data
          $BID: primaryId
        }
      }
    }
src/tabviews/zshare/normalTable/index.jsx
@@ -219,9 +219,15 @@
      let tabmenu = item.linkThdMenu
      tabmenu.param = {
        searchkey: item.field,
        searchval: record[item.field] || '',
        BID: record.$$uuid
        $searchkey: item.field,
        $searchval: record[item.field] || '',
        $BID: record.$$uuid
      }
      if (item.linkfields && item.linkfields.length > 0) {
        item.linkfields.forEach(field => {
          tabmenu.param[field] = record[field] || ''
        })
      }
  
      tabmenu.selected = true
@@ -257,8 +263,8 @@
          let _url = item.linkurl.split('paramsmain/')[0] + 'paramsmain/'
          let _param = JSON.parse(window.decodeURIComponent(window.atob(item.linkurl.split('paramsmain/')[1])))
          let dataparam = {
            searchkey: item.field,
            searchval: record[item.field] || '',
            $searchkey: item.field,
            $searchval: record[item.field] || '',
            BID: record[setting.primaryKey]
          }
          _param.UserID = sessionStorage.getItem('UserID')
src/templates/calendarconfig/index.jsx
@@ -23,6 +23,7 @@
const { Panel } = Collapse
const { confirm } = Modal
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
const SettingComponent = asyncComponent(() => import('@/templates/sharecomponent/settingcalcomponent'))
const TabComponent = asyncComponent(() => import('./tabcomponent'))
@@ -736,6 +737,10 @@
                  dict={this.state.dict}
                  updatemenu={this.updateconfig}
                />
                {config ? <UrlFieldComponent
                  config={config}
                  updateConfig={this.updateconfig}
                /> : null}
                {/* 表名添加 */}
                <TableComponent
                  config={config}
src/templates/comtableconfig/index.jsx
@@ -25,6 +25,7 @@
const { Panel } = Collapse
const { confirm } = Modal
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const EditComponent = asyncComponent(() => import('@/templates/zshare/editcomponent'))
const SettingComponent = asyncComponent(() => import('@/templates/sharecomponent/settingcomponent'))
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
@@ -1107,6 +1108,10 @@
                  dict={this.state.dict}
                  updatemenu={this.updateconfig}
                />
                {config ? <UrlFieldComponent
                  config={config}
                  updateConfig={this.updateconfig}
                /> : null}
                {/* 表名添加 */}
                <TableComponent
                  config={config}
src/templates/sharecomponent/columncomponent/columnform/index.jsx
@@ -34,9 +34,9 @@
    let _options = JSON.parse(JSON.stringify(columnTypeOptions[card.type]))
    if (card.type === 'text' || card.type === 'number') {
      if (card.perspective !== 'linkurl') {
        _options.push('linkmenu')
      } else {
      if (card.perspective === 'linkmenu') {
        _options.push('linkmenu', 'linkfields')
      } else if (card.perspective === 'linkurl') {
        _options.push('linkurl')
      }
    }
@@ -74,9 +74,9 @@
      let _options = JSON.parse(JSON.stringify(columnTypeOptions[value]))
      if (card.type === 'text' || card.type === 'number') {
        if (card.perspective !== 'linkurl') {
          _options.push('linkmenu')
        } else {
        if (card.perspective === 'linkmenu') {
          _options.push('linkmenu', 'linkfields')
        } else if (card.perspective === 'linkurl') {
          _options.push('linkurl')
        }
      }
@@ -107,10 +107,9 @@
  changeRadio = (key, value) => {
    if (key === 'perspective') {
      let _options = JSON.parse(JSON.stringify(columnTypeOptions[this.state.type]))
      if (value !== 'linkurl') {
        _options.push('linkmenu')
      } else {
      if (value === 'linkmenu') {
        _options.push('linkmenu', 'linkfields')
      } else if (value === 'linkurl') {
        _options.push('linkurl')
      }
@@ -283,7 +282,13 @@
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || []
                initialValue: item.initVal || [],
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Cascader
                  options={this.state.menulist}
src/templates/sharecomponent/columncomponent/index.jsx
@@ -73,6 +73,7 @@
   */
  handleColumn = (card) => {
    const { menu } = this.props
    const { columnlist } = this.state
    if (card.type !== 'colspan') {
      let menulist = []
@@ -99,11 +100,20 @@
          return fst
        })
      }
      let fields = []
      columnlist.forEach(col => {
        if (!col.field) return
        fields.push({
          value: col.field,
          text: col.label
        })
      })
      
      this.setState({
        modaltype: 'columns',
        card: card,
        formlist: getColumnForm(card, menulist)
        formlist: getColumnForm(card, menulist, fields)
      })
    } else {
      this.setState({
src/templates/sharecomponent/settingcalcomponent/verifycard/index.jsx
@@ -278,7 +278,7 @@
      let param = {
        func: 's_debug_sql',
        exec_type: 'y',
        LText: SettingUtils.getDebugSql(setting, _scripts, columns, Utils.getRegOptions(searches), config.calendar)
        LText: SettingUtils.getDebugSql(setting, _scripts, columns, Utils.getRegOptions(searches), config.calendar, config.urlFields)
      }
      param.LText = Utils.formatOptions(param.LText)
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
src/templates/sharecomponent/settingcalcomponent/verifycard/utils.jsx
@@ -7,7 +7,7 @@
   * @return {Object}  setting       页面设置
   * @return {Array}   columns       显示字段
   */
  static getDebugSql (setting, scripts, columns, searches, calendar) {
  static getDebugSql (setting, scripts, columns, searches, calendar, urlFields = []) {
    let sql = ''
    let _dataresource = ''
    let _customScript = ''
@@ -28,21 +28,22 @@
    }
    if (setting.execute !== 'false') {
      _dataresource = setting.dataresource
      _dataresource = setting.dataresource || ''
    }
    
    if (_dataresource) {
      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
    }
    if (_customScript) {
      _customScript = _customScript.replace(/@\$|\$@/ig, '')
    }
    _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
    _customScript = _customScript.replace(/@\$|\$@/ig, '')
    
    // 外联数据库替换
    if (window.GLOB.externalDatabase !== null) {
      _dataresource = _dataresource.replace(/@db@/ig, window.GLOB.externalDatabase)
      _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase)
    }
    urlFields.forEach(field => {
      _dataresource = _dataresource.replace(new RegExp('@' + field + '@', 'ig'), '0')
      _customScript = _customScript.replace(new RegExp('@' + field + '@', 'ig'), '0')
    })
    
    // 正则替换
    let _regoptions = []
@@ -62,13 +63,20 @@
      _regoptions.push({
        reg: new RegExp('@calendarDate@', 'ig'),
        value: `'1970-01-01 00:00:00.000'`
      })
      _regoptions.push({
      }, {
        reg: new RegExp('@calendarDate1@', 'ig'),
        value: `'2030-12-31 23:59:59.999'`
      })
    }
    _regoptions.push({
      reg: new RegExp('@userName@', 'ig'),
      value: `''`
    }, {
      reg: new RegExp('@fullName@', 'ig'),
      value: `''`
    })
    if ((setting.queryType === 'statistics' || calendar.refresh === 'true') && _dataresource) {
      _regoptions.forEach(item => {
        _dataresource = _dataresource.replace(item.reg, item.value)
src/templates/sharecomponent/settingcomponent/settingform/index.jsx
@@ -85,12 +85,23 @@
    status.requestMode = status.requestMode || 'system'
    status.procMode = status.procMode || 'script'
    status.callbackType = status.callbackType || 'script'
    let regoptions = Utils.getRegOptions(search)
    if (config.urlFields && config.urlFields.length > 0) {
      config.urlFields.forEach(field => {
        regoptions.push({
          key: field,
          value: '0',
          type: 'url'
        })
      })
    }
    this.setState({
      setting: _setting,
      search: _search,
      arr_field: arr_field.join(','),
      regoptions: Utils.getRegOptions(search), // 搜索条件,正则替换
      regoptions: regoptions, // 搜索条件,正则替换
      columns: columns,
      scripts: _scripts,
      preScripts: _preScripts,
src/templates/sharecomponent/settingcomponent/settingform/utils.jsx
@@ -43,11 +43,18 @@
    let _regoptions = regoptions.map(item => {
      return {
        reg: new RegExp('@' + item.key + '@', 'ig'),
        value: `'0'`
        value: `'0'`,
        type: item.type || ''
      }
    })
    _regoptions.push({
      reg: new RegExp('@userName@', 'ig'),
      value: `''`
    }, {
      reg: new RegExp('@fullName@', 'ig'),
      value: `''`
    }, {
      reg: new RegExp('@orderBy@', 'ig'),
      value: setting.order
    }, {
@@ -65,6 +72,11 @@
        _dataresource = _dataresource.replace(item.reg, item.value)
      })
      _search = ''
    } else if (_dataresource) {
      _regoptions.forEach(item => {
        if (item.type !== 'url') return
        _dataresource = _dataresource.replace(item.reg, item.value)
      })
    }
    if (_customScript) {
src/templates/zshare/formconfig.jsx
@@ -1135,7 +1135,7 @@
 * @param {object} card       // 搜索条件对象
 * @param {Array}  menulist   // 菜单列表-用于字段透视
 */
export function getColumnForm (card, menulist = []) {
export function getColumnForm (card, menulist = [], fields = []) {
  let roleList = sessionStorage.getItem('sysRoles')
  if (roleList) {
    try {
@@ -1145,6 +1145,10 @@
    }
  } else {
    roleList = []
  }
  if (!card.linkurl && (!card.linkmenu || card.linkmenu.length === 0)) {
    card.perspective = ''
  }
  return [
@@ -1394,8 +1398,11 @@
      type: 'radio',
      key: 'perspective',
      label: '字段透视',
      initVal: card.perspective || 'linkmenu',
      initVal: card.perspective || '',
      options: [{
        value: '',
        text: '无'
      }, {
        value: 'linkmenu',
        text: '菜单'
      }, {
@@ -1408,7 +1415,7 @@
      key: 'linkmenu',
      label: Formdict['model.menu'],
      initVal: card.linkmenu || [],
      required: false,
      required: true,
      options: menulist
    },
    {
@@ -1416,7 +1423,15 @@
      key: 'linkurl',
      label: '链接地址',
      initVal: card.linkurl || '',
      required: false
      required: true
    },
    {
      type: 'multiselect',
      key: 'linkfields',
      label: '关联字段',
      initVal: card.linkfields || [],
      required: false,
      options: fields
    },
    {
      type: 'multiselect',
src/utils/utils-datamanage.js
@@ -126,10 +126,10 @@
      })
      regoptions.push({
        reg: new RegExp('@userName@', 'ig'),
        value: userName
        value: `'${userName}'`
      }, {
        reg: new RegExp('@fullName@', 'ig'),
        value: fullName
        value: `'${fullName}'`
      }, {
        reg: new RegExp('@orderBy@', 'ig'),
        value: orderBy
@@ -254,10 +254,10 @@
      })
      regoptions.push({
        reg: new RegExp('@userName@', 'ig'),
        value: userName
        value: `'${userName}'`
      }, {
        reg: new RegExp('@fullName@', 'ig'),
        value: fullName
        value: `'${fullName}'`
      }, {
        reg: new RegExp('@orderBy@', 'ig'),
        value: orderBy
@@ -399,10 +399,10 @@
      })
      regoptions.push({
        reg: new RegExp('@userName@', 'ig'),
        value: userName
        value: `'${userName}'`
      }, {
        reg: new RegExp('@fullName@', 'ig'),
        value: fullName
        value: `'${fullName}'`
      })
      regoptions.forEach(item => {
src/views/billprint/index.jsx
@@ -197,6 +197,12 @@
            component.setting.dataresource = component.setting.dataresource.replace(/@\$|\$@/ig, '')
            _customScript = _customScript.replace(/@\$|\$@/ig, '')
          }
          // 外联数据库替换
          if (window.GLOB.externalDatabase !== null) {
            component.setting.dataresource = component.setting.dataresource.replace(/@db@/ig, window.GLOB.externalDatabase)
            _customScript = _customScript.replace(/@db@/ig, window.GLOB.externalDatabase)
          }
    
          component.setting.customScript = _customScript // 整理后自定义脚本
    
src/views/menudesign/index.jsx
@@ -37,6 +37,7 @@
const PaddingController = asyncComponent(() => import('@/menu/padcontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const SysInterface = asyncComponent(() => import('@/menu/sysinterface'))
const UrlFieldComponent = asyncComponent(() => import('@/menu/urlfieldcomponent'))
const PictureController = asyncComponent(() => import('@/menu/picturecontroller'))
const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller'))
const StyleCombController = asyncComponent(() => import('@/menu/stylecombcontroller'))
@@ -47,6 +48,7 @@
sessionStorage.setItem('editMenuType', 'menu') // 编辑菜单类型
document.body.className = ''
window.GLOB.UserComponentMap = new Map() // 缓存用户自定义组件
window.GLOB.urlFields = []               // url变量
class MenuDesign extends Component {
  state = {
@@ -334,6 +336,7 @@
        }
        config.open_edition = result.open_edition || ''
        window.GLOB.urlFields = config.urlFields || []
        this.setState({
          oriConfig: config,
@@ -901,6 +904,10 @@
                      MenuNo={MenuNo}
                      updateConfig={this.updateConfig}
                    /> : null}
                    {config && MenuType === 'custom' ? <UrlFieldComponent
                      config={config}
                      updateConfig={this.updateConfig}
                    /> : null}
                    {config && MenuType === 'home' ? <HomeForm
                      dict={dict}
                      config={config}
src/views/menudesign/menuform/index.jsx
@@ -107,13 +107,6 @@
    })
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    const { config } = this.props
    if (!config && nextProps.config) {
      this.props.form.setFieldsValue({easyCode: nextProps.config.easyCode})
    }
  }
  // 一二级菜单切换
  selectChange = (key, value) => {
    const { config } = this.props