king
2020-05-14 eb31b84962c192de57abbb473cb4733a09bf4363
2020-05-14
38个文件已修改
7个文件已添加
1941 ■■■■ 已修改文件
src/components/header/index.jsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/editsecmenu/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/model.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/model.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action-type.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/action.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/reducer.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/commontable/index.jsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/formtab/index.jsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/managetable/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/managetable/secretKeyTable/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/scriptmanage/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtable/index.jsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/subtabtable/index.jsx 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/verupmanage/subtabtable/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/index.jsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/dategroup/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/mutilform/index.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/normalTable/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/topSearch/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/modalconfig/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/actionform/index.jsx 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/index.jsx 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/chartcompile/index.jsx 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/chartcompile/index.scss 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/dragdetail/index.jsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/dragdetail/index.scss 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/index.jsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/index.scss 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartgroupcomponent/chartform/index.jsx 110 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartgroupcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/searchcomponent/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/customscript/index.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/index.jsx 180 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/option.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 106 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx
@@ -16,6 +16,7 @@
  resetEditState,
  resetEditLevel,
  initPermission,
  modifyDataManager,
  initActionPermission,
  initMenuPermission,
  logout
@@ -196,6 +197,10 @@
        }),
        systems: result.Systems.filter(sys => sys.LinkUrl1 && sys.AppKey !== window.GLOB.appkey)
      })
      if (result.dataM) {
        this.props.modifyDataManager(true)
      }
    } else {
      notification.error({
        top: 92,
@@ -270,6 +275,10 @@
            }),
            systems: result.Systems.filter(sys => sys.LinkUrl1 && sys.AppKey !== window.GLOB.appkey)
          })
          if (result.dataM) {
            this.props.modifyDataManager(true)
          }
        } else if (result) {
          notification.error({
            top: 92,
@@ -764,6 +773,7 @@
    initActionPermission: (permRoles, permAction) => dispatch(initActionPermission(permRoles, permAction)),
    initPermission: (sysRoles, permFuncField) => dispatch(initPermission(sysRoles, permFuncField)),
    initMenuPermission: (permMenus) => dispatch(initMenuPermission(permMenus)),
    modifyDataManager: (dataManager) => dispatch(modifyDataManager(dataManager)),
    resetState: () => dispatch(resetState()),
    resetDebug: () => dispatch(resetDebug()),
    logout: () => dispatch(logout())
src/components/sidemenu/editsecmenu/index.jsx
@@ -399,11 +399,11 @@
          </div>
        </div>
        <DndProvider backend={HTML5Backend}>
          <DragElement
          {this.state.menulist && this.state.menulist.length > 0 ? <DragElement
            list={this.state.menulist}
            handlePreviewList={this.handlePreviewList}
            handleMenu={this.handleMenu}
          />
          /> : null}
        </DndProvider>
        <div className="menu-add" onClick={() => {this.handleSubBtn('add')}}>
          <Icon type="plus" />
src/components/sidemenu/index.jsx
@@ -41,7 +41,7 @@
  async loadsubmenu (menu) {
    if (!menu || !menu.MenuID) { // 没有主菜单时,清空下级菜单
      this.setState({
        subMenulist: [],
        subMenulist: null,
        rootSubmenuKeys: [],
        openKeys: [],
        editMenu: null
@@ -61,10 +61,9 @@
      
      if (result.data.length === 0) { // 查询菜单为空
        this.setState({
          subMenulist: [],
          subMenulist: null,
          rootSubmenuKeys: [],
          openKeys: [],
          editMenu: null
          openKeys: []
        })
        return
      }
@@ -289,10 +288,10 @@
    return (
      <aside className={"side-menu ant-menu-dark" + (this.props.collapse ? ' side-menu-collapsed' : '') + (this.props.isiframe ? ' iframe' : '')}>
        {this.state.subMenulist && !(this.props.editLevel === 'level2' || this.props.editLevel === 'level3') &&
        {!(this.props.editLevel === 'level2' || this.props.editLevel === 'level3') &&
          <Menu openKeys={this.state.openKeys} onOpenChange={this.onOpenChange} mode="inline" theme="dark" inlineCollapsed={this.props.collapse}>
          {editShow && <li className="sup-menu"><Icon onClick={this.enterSubEdit} className="edit-check" type="edit" /></li>}
          {this.state.subMenulist.map((item, index) => {
          {this.state.subMenulist && this.state.subMenulist.map((item, index) => {
            return (
              <SubMenu
                key={item.MenuID}
@@ -326,14 +325,14 @@
            exitEdit={this.exitEdit}
          />
        }
        {this.props.editLevel === 'level3' && this.state.subMenulist &&
        {this.props.editLevel === 'level3' && this.state.subMenulist ?
          <EditThdMenu
            menulist={this.state.editMenu.children}
            supMenuList={this.state.subMenulist}
            supMenu={this.state.editMenu}
            reload={this.reload}
            exitEdit={this.exitEdit}
          />
          /> : null
        }
      </aside>
    )
src/locales/en-US/model.js
@@ -167,6 +167,7 @@
  'header.form.action.type': '操作类型',
  'header.form.action.insert': '添加',
  'header.form.action.update': '修改',
  'header.form.action.audit': '审核',
  'header.form.action.insertOrUpdate': '添加或修改',
  'header.form.action.LogicDelete': '逻辑删除',
  'header.form.action.delete': '物理删除',
src/locales/zh-CN/model.js
@@ -167,6 +167,7 @@
  'header.form.action.type': '操作类型',
  'header.form.action.insert': '添加',
  'header.form.action.update': '修改',
  'header.form.action.audit': '审核',
  'header.form.action.insertOrUpdate': '添加或修改',
  'header.form.action.LogicDelete': '逻辑删除',
  'header.form.action.delete': '物理删除',
src/store/action-type.js
@@ -37,5 +37,8 @@
// 修改会员等级
export const MODIFY_MEMBERLEVEL = 'MODIFY_MEMBERLEVEL'
// 修改数据权限
export const MODIFY_DATAMANAGER = 'MODIFY_DATAMANAGER'
// 退出
export const LOGOUT = 'LOGOUT'
src/store/action.js
@@ -104,6 +104,14 @@
  }
}
// 初始数据权限
export const modifyDataManager = (dataManager) => {
  return {
    type: user.MODIFY_DATAMANAGER,
    dataManager: dataManager
  }
}
// 退出重置
export const logout = () => {
  return {
src/store/reducer.js
@@ -1,6 +1,20 @@
import md5 from 'md5'
import moment from 'moment'
import * as Type from './action-type'
let _collapse = localStorage.getItem('collapse') === 'true'
let _level = 10
let _Mlevel = sessionStorage.getItem('Member_Level')
if (_Mlevel) {
  if (_Mlevel === md5('mksoft' + moment().format('YYYYMM') + 10)) {
    _level = 10
  } else if (_Mlevel === md5('mksoft' + moment().format('YYYYMM') + 20)) {
    _level = 20
  } else if (_Mlevel === md5('mksoft' + moment().format('YYYYMM') + 30)) {
    _level = 30
  }
}
let defaultState = {
  selectedMainMenu: '', // 已选主菜单
@@ -17,7 +31,7 @@
  permFuncField: [],    // 系统模块
  sysRoles: [],         // 系统角色列表
  dataManager: false,   // 数据管理员
  memberLevel: 10       // 会员等级
  memberLevel: _level   // 会员等级
}
// 用户消息
@@ -121,6 +135,12 @@
        ...state,
        memberLevel: action.memberLevel
      }
    case Type.MODIFY_DATAMANAGER:
      // 修改数据权限
      return {
        ...state,
        dataManager: action.dataManager
      }
    case Type.LOGOUT:
      return {
        selectedMainMenu: '',
src/tabviews/commontable/index.jsx
@@ -72,7 +72,8 @@
    revertLoading: false, // 恢复默认设置
    settingVisible: false,// 自定义设置模态框
    triggerBtn: null,     // 点击表格中或快捷键触发的按钮
    tabActive: null       // 标签页展开控制
    tabActive: null,      // 标签页展开控制
    chartId: ''           // 展开图表ID
  }
  /**
@@ -148,8 +149,9 @@
      }
  
      // 兼容图表
      let chartId = ''
      if (!config.charts) {
        config.expand = false
        config.expand = true
        config.charts = [{
          uuid: Utils.getuuid(),
          label: '',
@@ -159,7 +161,10 @@
          Hide: 'false',
          blacklist: []
        }]
      } else if (config.charts.length === 1) {
        config.expand = true
      }
      chartId = config.charts[0].uuid
      // 权限过滤
      config.action = config.action.filter(item => permAction[item.uuid])
@@ -349,6 +354,7 @@
      this.setState({
        loadingview: false,
        chartId: chartId,
        config: config,
        tabActive: _tabActive,
        userConfig: userConfig,
@@ -503,6 +509,13 @@
          arr_field: _option.field
        }
        if (this.props.dataManager) { // 数据权限
          param.LText = param.LText.replace(/\$@/ig, '/*')
          param.LText = param.LText.replace(/@\$/ig, '*/')
        } else {
          param.LText = param.LText.replace(/@\$|\$@/ig, '')
        }
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -634,6 +647,7 @@
    let param = {
      OrderCol: orderBy || setting.order,
      dataM: this.props.dataManager ? 'Y' : '',
      ..._search
    }
@@ -683,7 +697,8 @@
      obj_name: 'data',
      arr_field: arr_field,
      custom_script: setting.customScript || '',
      default_sql: setting.default || 'true'
      default_sql: setting.default || 'true',
      dataM: this.props.dataManager ? 'Y' : ''
    }
    
    let _orderBy = orderBy || setting.order
@@ -691,6 +706,16 @@
    if (/\s/.test(_dataresource)) {
      _dataresource = '(' + _dataresource + ') tb'
    }
    if (this.props.dataManager) { // 数据权限
      _dataresource = _dataresource.replace(/\$@/ig, '/*')
      _dataresource = _dataresource.replace(/@\$/ig, '*/')
      param.custom_script = param.custom_script.replace(/\$@/ig, '/*')
      param.custom_script = param.custom_script.replace(/@\$/ig, '*/')
    } else {
      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
      param.custom_script = param.custom_script.replace(/@\$|\$@/ig, '')
    }
    let regoptions = null
@@ -1225,6 +1250,13 @@
    })
  }
  /**
   * @description 图表视图切换
   */
  changeChart = (uuid) => {
    this.setState({chartId: uuid})
  }
  UNSAFE_componentWillMount () {
    // 组件加载时,获取菜单数据
    this.loadconfig()
@@ -1270,7 +1302,7 @@
  }
  render() {
    const { view, setting, searchlist, actions, columns, loadingview, viewlost, pickup, config, triggerBtn, userConfig, tabActive, search } = this.state
    const { view, setting, searchlist, actions, columns, loadingview, viewlost, pickup, config, triggerBtn, userConfig, tabActive, chartId, search } = this.state
    return (
      <div>
@@ -1286,73 +1318,14 @@
          }
          {setting && setting.onload !== 'false' ? <div className="chart-view">
            {/* 视图组 */}
            {!config.expand ? <Tabs>
            {!config.expand ? <Tabs activeKey={chartId} onChange={this.changeChart}>
              {config.charts.map(item => (
                <TabPane tab={
                  <Icon type={item.icon} />
                } key={item.uuid}>
                  {item.chartType === 'table' ?
                    <Col span={item.width || 24} key={item.uuid}>
                      {config.charts.length > 1 ? <p className="chart-table chart-title">{item.title}</p> : null}
                      <div style={{minHeight: '25px'}}>
                        <MainAction
                          BID=""
                          type="main"
                          menuType="main"
                          setting={setting}
                          actions={actions}
                          triggerBtn={triggerBtn}
                          dict={this.state.dict}
                          MenuID={this.props.MenuID}
                          permRoles={this.props.permRoles}
                          logcolumns={this.state.logcolumns}
                          ContainerId={this.state.ContainerId}
                          refreshdata={this.refreshbyaction}
                          triggerPopview={this.triggerPopview}
                          getexceloutparam={this.getexceloutparam}
                          gettableselected={this.gettableselected}
                        />
                      </div>
                      <div className="main-table-box">
                        <Icon className="custom-control" type="setting" onClick={this.controlCustomSetting} />
                        {this.state.data && this.state.data.length > 0 ?
                          <Switch title="收起" className="main-pickup" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null
                        }
                        <MainTable
                          ref="mainTable"
                          tableId="mainTable"
                          pickup={pickup}
                          config={config}
                          setting={setting}
                          columns={columns}
                          dict={this.state.dict}
                          data={this.state.data}
                          total={this.state.total}
                          MenuID={this.props.MenuID}
                          memberLevel={this.props.memberLevel}
                          loading={this.state.loading}
                          pagination={setting.laypage !== 'false'}
                          refreshdata={this.refreshbytable}
                          buttonTrigger={this.buttonTrigger}
                          linkTrigger={this.linkTrigger}
                          handleTableId={this.handleTableId}
                        />
                      </div>
                    </Col> : null
                  }
                  {item.chartType !== 'table' ?
                    <Col span={item.width} key={item.uuid}>
                      <ChartComponent
                        plot={item}
                        data={this.state.data}
                        config={config}
                      />
                    </Col> : null
                  }
                </TabPane>
                <TabPane tab={<Icon type={item.icon} />} key={item.uuid}></TabPane>
              ))}
            </Tabs> : null}
            {config.expand && config.charts.map(item => {
            {config.charts.map(item => {
              if (!config.expand && chartId !== item.uuid) return null
              if (item.chartType === 'table') {
                return (
                  <Col span={item.width || 24} key={item.uuid}>
@@ -1368,6 +1341,7 @@
                        dict={this.state.dict}
                        MenuID={this.props.MenuID}
                        permRoles={this.props.permRoles}
                        dataManager={this.props.dataManager}
                        logcolumns={this.state.logcolumns}
                        ContainerId={this.state.ContainerId}
                        refreshdata={this.refreshbyaction}
@@ -1401,6 +1375,16 @@
                        handleTableId={this.handleTableId}
                      />
                    </div>
                  </Col>
                )
              } else if (item.chartType === 'card') {
                return (
                  <Col span={item.width} key={item.uuid}>
                    <ChartComponent
                      plot={item}
                      data={this.state.data}
                      config={config}
                    />
                  </Col>
                )
              } else {
@@ -1545,7 +1529,8 @@
    permAction: state.permAction,
    permMenus: state.permMenus,
    permRoles: state.permRoles,
    memberLevel: state.memberLevel
    memberLevel: state.memberLevel,
    dataManager: state.dataManager
  }
}
src/tabviews/formtab/index.jsx
@@ -205,6 +205,13 @@
            obj_name: 'data',
            arr_field: _option.field
          }
          if (this.props.dataManager) { // 数据权限
            param.LText = param.LText.replace(/\$@/ig, '/*')
            param.LText = param.LText.replace(/@\$/ig, '*/')
          } else {
            param.LText = param.LText.replace(/@\$|\$@/ig, '')
          }
  
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
          param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -390,13 +397,24 @@
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field,
      ID: primaryId
      ID: primaryId,
      dataM: this.props.dataManager ? 'Y' : ''
    }
    
    let _dataresource = setting.dataresource
    if (/\s/.test(_dataresource)) {
      _dataresource = '(' + _dataresource + ') tb'
    }
    if (this.props.dataManager) { // 数据权限
      _dataresource = _dataresource.replace(/\$@/ig, '/*')
      _dataresource = _dataresource.replace(/@\$/ig, '*/')
      // param.custom_script = param.custom_script.replace(/\$@/ig, '/*')
      // param.custom_script = param.custom_script.replace(/@\$/ig, '*/')
    } else {
      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
      // param.custom_script = param.custom_script.replace(/@\$|\$@/ig, '')
    }
    if (!/@ID@/ig.test(_dataresource)) {
@@ -419,7 +437,9 @@
  getCustomParam = () => {
    const { setting, primaryId } = this.state
    let param = {}
    let param = {
      dataM: this.props.dataManager ? 'Y' : ''
    }
    if (setting.interType === 'inner') {
      param.func = setting.innerFunc
@@ -705,6 +725,7 @@
    tabviews: state.tabviews,
    refreshTab: state.refreshTab,
    permAction: state.permAction,
    dataManager: state.dataManager,
    permRoles: state.permRoles
  }
}
src/tabviews/managetable/index.jsx
@@ -249,6 +249,13 @@
          arr_field: _option.field
        }
        if (this.props.dataManager) { // 数据权限
          param.LText = param.LText.replace(/\$@/ig, '/*')
          param.LText = param.LText.replace(/@\$/ig, '*/')
        } else {
          param.LText = param.LText.replace(/@\$|\$@/ig, '')
        }
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -365,10 +372,14 @@
    let _search = Utils.formatCustomMainSearch(search)
    let param = {
      PageIndex: pageIndex,
      PageSize: pageSize,
      OrderCol: orderBy || setting.order,
      dataM: this.props.dataManager ? 'Y' : '',
      ..._search
    }
    if (setting.laypage !== 'false') {
      param.PageIndex = pageIndex
      param.PageSize = pageSize
    }
    if (setting.interType === 'inner') {
@@ -412,7 +423,8 @@
      obj_name: 'data',
      arr_field: arr_field,
      custom_script: setting.customScript || '',
      default_sql: setting.default || 'true'
      default_sql: setting.default || 'true',
      dataM: this.props.dataManager ? 'Y' : ''
    }
    
    let _orderBy = orderBy || setting.order
@@ -420,6 +432,16 @@
    if (/\s/.test(_dataresource)) {
      _dataresource = '(' + _dataresource + ') tb'
    }
    if (this.props.dataManager) { // 数据权限
      _dataresource = _dataresource.replace(/\$@/ig, '/*')
      _dataresource = _dataresource.replace(/@\$/ig, '*/')
      param.custom_script = param.custom_script.replace(/\$@/ig, '/*')
      param.custom_script = param.custom_script.replace(/@\$/ig, '*/')
    } else {
      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
      param.custom_script = param.custom_script.replace(/@\$|\$@/ig, '')
    }
    let regoptions = null
@@ -896,6 +918,7 @@
              dict={this.state.dict}
              triggerBtn={triggerBtn}
              MenuID={this.props.MenuID}
              dataManager={this.props.dataManager}
              logcolumns={this.state.logcolumns}
              ContainerId={this.state.ContainerId}
              refreshdata={this.refreshbyaction}
@@ -916,6 +939,7 @@
                menuType="HS"
                tableId="mainTable"
                pickup={pickup}
                config={config}
                setting={setting}
                columns={columns}
                dict={this.state.dict}
@@ -1037,6 +1061,7 @@
  return {
    tabviews: state.tabviews,
    refreshTab: state.refreshTab,
    dataManager: state.dataManager,
    permAction: state.permAction
  }
}
src/tabviews/managetable/secretKeyTable/index.jsx
@@ -340,7 +340,7 @@
  }
  render() {
    const { setting, actions, columns, pickup } = this.state
    const { setting, actions, columns, pickup, config } = this.state
    return (
      <div className="subtable" id={'subtable' + this.props.MenuID}>
@@ -371,6 +371,7 @@
            menuType="HS"
            tableId={this.props.Tab.uuid}
            pickup={pickup}
            config={config}
            setting={setting}
            columns={columns}
            pagination={false}
src/tabviews/scriptmanage/index.jsx
@@ -313,7 +313,7 @@
  }
  render() {
    const { dict, searchlist, setting, actions, columns, pickup } = this.state
    const { dict, searchlist, config, setting, actions, columns, pickup } = this.state
    return (
      <div className="veruptable pick-control" id={this.state.ContainerId}>
@@ -345,6 +345,7 @@
            menuType="HS"
            tableId="mainTable"
            pickup={pickup}
            config={config}
            setting={setting}
            columns={columns}
            dict={this.state.dict}
src/tabviews/subtable/index.jsx
@@ -65,7 +65,8 @@
    popData: false,       // 弹框页面,所选的表格数据
    visible: false,       // 弹框显示隐藏控制
    pickup: false,        // 子表数据隐藏显示切换
    triggerBtn: null      // 按钮触发
    triggerBtn: null,     // 按钮触发
    chartId: ''           // 展开图表ID
  }
  /**
@@ -139,8 +140,9 @@
      let colMap = new Map()
      // 兼容图表
      let chartId = ''
      if (!config.charts) {
        config.expand = false
        config.expand = true
        config.charts = [{
          uuid: Utils.getuuid(),
          label: '',
@@ -150,7 +152,10 @@
          Hide: 'false',
          blacklist: []
        }]
      } else if (config.charts.length === 1) {
        config.expand = true
      }
      chartId = config.charts[0].uuid
      // 权限过滤
      if (this.props.menuType !== 'HS') {
@@ -320,6 +325,7 @@
      this.setState({
        loadingview: false,
        chartId: chartId,
        config: config,
        setting: config.setting,
        searchlist: config.search,
@@ -380,6 +386,12 @@
        if (this.props.BID) {
          param.BID = this.props.BID
        }
        if (this.props.dataManager) { // 数据权限
          param.LText = param.LText.replace(/\$@/ig, '/*')
          param.LText = param.LText.replace(/@\$/ig, '*/')
        } else {
          param.LText = param.LText.replace(/@\$|\$@/ig, '')
        }
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
@@ -531,6 +543,7 @@
    let param = {
      OrderCol: orderBy || setting.order,
      dataM: this.props.dataManager ? 'Y' : '',
      BID: BID,
      ..._search
    }
@@ -586,7 +599,8 @@
      arr_field: arr_field,
      BID: BID,
      custom_script: setting.customScript || '',
      default_sql: setting.default || 'true'
      default_sql: setting.default || 'true',
      dataM: this.props.dataManager ? 'Y' : ''
    }
    let _orderBy = orderBy || setting.order
@@ -594,6 +608,16 @@
    if (/\s/.test(_dataresource)) {
      _dataresource = '(' + _dataresource + ') tb'
    }
    if (this.props.dataManager) { // 数据权限
      _dataresource = _dataresource.replace(/\$@/ig, '/*')
      _dataresource = _dataresource.replace(/@\$/ig, '*/')
      param.custom_script = param.custom_script.replace(/\$@/ig, '/*')
      param.custom_script = param.custom_script.replace(/@\$/ig, '*/')
    } else {
      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
      param.custom_script = param.custom_script.replace(/@\$|\$@/ig, '')
    }
    let regoptions = null
@@ -866,6 +890,13 @@
    this.refreshbyaction(this.state.popAction, 'pop')
  }
  /**
   * @description 图表视图切换
   */
  changeChart = (uuid) => {
    this.setState({chartId: uuid})
  }
  UNSAFE_componentWillMount() {
    // 组件加载时,获取菜单数据
    this.loadconfig()
@@ -885,7 +916,7 @@
  }
  render() {
    const { config, setting, searchlist, actions, columns, loadingview, viewlost, pickup, triggerBtn } = this.state
    const { config, setting, searchlist, actions, columns, loadingview, viewlost, pickup, triggerBtn, chartId } = this.state
    return (
      <div className="subtable" id={'subtable' + this.props.MenuID}>
@@ -899,75 +930,13 @@
        }
        {config ? <div className="chart-view">
          {/* 视图组 */}
          {!config.expand ? <Tabs>
          {!config.expand ? <Tabs activeKey={chartId} onChange={this.changeChart}>
            {config.charts.map(item => (
              <TabPane tab={
                <Icon type={item.icon} />
              } key={item.uuid}>
                {item.chartType === 'table' ?
                  <Col span={item.width || 24} key={item.uuid}>
                    {config.charts.length > 1 ? <p className="chart-table chart-title">{item.title}</p> : null}
                    <div className="sub-action">
                      <SubAction
                        type="sub"
                        menuType={this.props.menuType}
                        triggerBtn={triggerBtn}
                        setting={setting}
                        actions={actions}
                        Tab={this.props.Tab}
                        BID={this.props.BID}
                        BData={this.props.BData}
                        dict={this.state.dict}
                        MenuID={this.props.MenuID}
                        permRoles={this.props.permRoles}
                        logcolumns={this.state.logcolumns}
                        refreshdata={this.refreshbyaction}
                        ContainerId={this.props.ContainerId}
                        triggerPopview={this.triggerPopview}
                        getexceloutparam={this.getexceloutparam}
                        gettableselected={this.gettableselected}
                      />
                    </div>
                    <div className="subtable-box">
                      {this.state.data && this.state.data.length > 0 ?
                        <Switch title="收起" className="subtable-pickup" checkedChildren="开" unCheckedChildren="关" defaultChecked={pickup} onChange={this.pickupChange} /> : null
                      }
                      <SubTable
                        ref="subTable"
                        menuType={this.props.menuType}
                        tableId={this.props.Tab.uuid}
                        pickup={pickup}
                        config={config}
                        setting={setting}
                        columns={columns}
                        dict={this.state.dict}
                        data={this.state.data}
                        total={this.state.total}
                        MenuID={this.props.MenuID}
                        memberLevel={this.props.memberLevel}
                        loading={this.state.loading}
                        pagination={setting.laypage !== 'false'}
                        refreshdata={this.refreshbytable}
                        buttonTrigger={this.buttonTrigger}
                        linkTrigger={this.linkTrigger}
                        handleTableId={this.handleTableId}
                      />
                    </div>
                  </Col> : null
                }
                {item.chartType !== 'table' ?
                  <Col span={item.width} key={item.uuid}>
                    <ChartComponent
                      plot={item}
                      data={this.state.data}
                      config={config}
                    />
                  </Col> : null
                }
              </TabPane>
              <TabPane tab={<Icon type={item.icon} />} key={item.uuid}></TabPane>
            ))}
          </Tabs> : null}
          {config.expand && config.charts.map(item => {
            if (!config.expand && chartId !== item.uuid) return null
            if (item.chartType === 'table') {
              return (
                <Col span={item.width || 24} key={item.uuid}>
@@ -984,6 +953,7 @@
                      BData={this.props.BData}
                      dict={this.state.dict}
                      MenuID={this.props.MenuID}
                      dataManager={this.props.dataManager}
                      permRoles={this.props.permRoles}
                      logcolumns={this.state.logcolumns}
                      refreshdata={this.refreshbyaction}
@@ -1068,6 +1038,7 @@
    permAction: state.permAction,
    permRoles: state.permRoles,
    permMenus: state.permMenus,
    dataManager: state.dataManager,
    memberLevel: state.memberLevel
  }
}
src/tabviews/subtabtable/index.jsx
@@ -53,7 +53,8 @@
    pageSize: 10,         // 每页数据条数
    orderBy: '',          // 排序
    search: '',           // 搜索条件数组,使用时需分场景处理
    triggerBtn: null      // 按钮触发
    triggerBtn: null,     // 按钮触发
    chartId: ''           // 展开图表ID
  }
  /**
@@ -103,8 +104,9 @@
      let colMap = new Map()
      // 兼容图表
      let chartId = ''
      if (!config.charts) {
        config.expand = false
        config.expand = true
        config.charts = [{
          uuid: Utils.getuuid(),
          label: '',
@@ -114,7 +116,10 @@
          Hide: 'false',
          blacklist: []
        }]
      } else if (config.charts.length === 1) {
        config.expand = true
      }
      chartId = config.charts[0].uuid
      // 仅支持exec、prompt、pop 三种类型按钮
      config.action = config.action.filter(item => ['exec', 'prompt', 'pop'].includes(item.OpenType))
@@ -241,6 +246,7 @@
      this.setState({
        loadingview: false,
        chartId: chartId,
        config: config,
        setting: config.setting,
        searchlist: config.search,
@@ -299,6 +305,12 @@
        if (this.props.BID) {
          param.BID = this.props.BID
        }
        if (this.props.dataManager) { // 数据权限
          param.LText = param.LText.replace(/\$@/ig, '/*')
          param.LText = param.LText.replace(/@\$/ig, '*/')
        } else {
          param.LText = param.LText.replace(/@\$|\$@/ig, '')
        }
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
@@ -414,6 +426,7 @@
    let param = {
      OrderCol: orderBy || setting.order,
      dataM: this.props.dataManager ? 'Y' : '',
      ..._search
    }
@@ -462,7 +475,8 @@
      arr_field: arr_field,
      BID: this.props.BID,
      custom_script: setting.customScript || '',
      default_sql: setting.default || 'true'
      default_sql: setting.default || 'true',
      dataM: this.props.dataManager ? 'Y' : ''
    }
    let _orderBy = orderBy || setting.order
@@ -470,6 +484,16 @@
    if (/\s/.test(_dataresource)) {
      _dataresource = '(' + _dataresource + ') tb'
    }
    if (this.props.dataManager) { // 数据权限
      _dataresource = _dataresource.replace(/\$@/ig, '/*')
      _dataresource = _dataresource.replace(/@\$/ig, '*/')
      param.custom_script = param.custom_script.replace(/\$@/ig, '/*')
      param.custom_script = param.custom_script.replace(/@\$/ig, '*/')
    } else {
      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
      param.custom_script = param.custom_script.replace(/@\$|\$@/ig, '')
    }
    let regoptions = null
@@ -647,6 +671,13 @@
    })
  }
  /**
   * @description 图表视图切换
   */
  changeChart = (uuid) => {
    this.setState({chartId: uuid})
  }
  UNSAFE_componentWillMount () {
    // 组件加载时,获取菜单数据
    this.loadconfig()
@@ -666,7 +697,7 @@
  }
  render() {
    const { config, setting, searchlist, actions, columns, loadingview, viewlost, triggerBtn } = this.state
    const { config, setting, searchlist, actions, columns, loadingview, viewlost, triggerBtn, chartId } = this.state
    return (
      <div className="subtabtable" id={'subtabtable' + this.props.MenuID}>
@@ -680,65 +711,14 @@
        }
        {config ? <div className="chart-view">
          {/* 视图组 */}
          {!config.expand ? <Tabs>
          {!config.expand ? <Tabs activeKey={chartId} onChange={this.changeChart}>
            {config.charts.map(item => (
              <TabPane tab={
                <Icon type={item.icon} />
              } key={item.uuid}>
                {item.chartType === 'table' ?
                  <Col span={item.width || 24} key={item.uuid}>
                    {config.charts.length > 1 ? <p className="chart-table chart-title">{item.title}</p> : null}
                    <div style={{minHeight: '25px'}}>
                      <SubAction
                        type="subtab"
                        triggerBtn={triggerBtn}
                        menuType={this.props.menuType}
                        setting={setting}
                        actions={actions}
                        BID={this.props.BID}
                        dict={this.state.dict}
                        BData={this.props.BData}
                        MenuID={this.props.SupMenuID}
                        permRoles={this.props.permRoles}
                        logcolumns={this.state.logcolumns}
                        refreshdata={this.refreshbyaction}
                        ContainerId={this.props.ContainerId}
                        gettableselected={this.gettableselected}
                      />
                    </div>
                    <SubTable
                      ref="subTable"
                      menuType={this.props.menuType}
                      tableId=""
                      dict={this.state.dict}
                      MenuID={this.props.MenuID}
                      config={config}
                      setting={setting}
                      columns={columns}
                      data={this.state.data}
                      total={this.state.total}
                      memberLevel={this.props.memberLevel}
                      loading={this.state.loading}
                      pagination={setting.laypage !== 'false'}
                      refreshdata={this.refreshbytable}
                      buttonTrigger={this.buttonTrigger}
                      handleTableId={() => {}}
                    />
                  </Col> : null
                }
                {item.chartType !== 'table' ?
                  <Col span={item.width} key={item.uuid}>
                    <ChartComponent
                      plot={item}
                      data={this.state.data}
                      config={config}
                    />
                  </Col> : null
                }
              </TabPane>
              <TabPane tab={<Icon type={item.icon} />} key={item.uuid}></TabPane>
            ))}
          </Tabs> : null}
          {config.expand && config.charts.map(item => {
            if (!config.expand && chartId !== item.uuid) return null
            if (item.chartType === 'table') {
              return (
                <Col span={item.width || 24} key={item.uuid}>
@@ -755,6 +735,7 @@
                      BData={this.props.BData}
                      MenuID={this.props.SupMenuID}
                      permRoles={this.props.permRoles}
                      dataManager={this.props.dataManager}
                      logcolumns={this.state.logcolumns}
                      refreshdata={this.refreshbyaction}
                      ContainerId={this.props.ContainerId}
@@ -804,6 +785,7 @@
  return {
    permAction: state.permAction,
    permRoles: state.permRoles,
    dataManager: state.dataManager,
    memberLevel: state.memberLevel
  }
}
src/tabviews/verupmanage/index.jsx
@@ -472,6 +472,7 @@
            menuType="HS"
            tableId="mainTable"
            pickup={pickup}
            config={config}
            setting={setting}
            columns={columns}
            dict={this.state.dict}
src/tabviews/verupmanage/subtabtable/index.jsx
@@ -426,7 +426,7 @@
  }
  render() {
    const { setting, searchlist, actions, columns, pickup } = this.state
    const { config, setting, searchlist, actions, columns, pickup } = this.state
    return (
      <div className="subtable" id={'subtable' + this.props.MenuID}>
@@ -467,6 +467,7 @@
              menuType="HS"
              tableId={this.props.Tab.uuid}
              pickup={pickup}
              config={config}
              setting={setting}
              columns={columns}
              dict={this.state.dict}
src/tabviews/zshare/actionList/index.jsx
@@ -32,7 +32,8 @@
    getexceloutparam: PropTypes.func, // 获取excel导出数据
    gettableselected: PropTypes.func, // 获取表格中数据
    permRoles: PropTypes.any,         // 用户权限列表
    triggerBtn: PropTypes.any
    triggerBtn: PropTypes.any,
    dataManager: PropTypes.any        // 数据权限
  }
  state = {
@@ -1099,7 +1100,7 @@
      if (
        btn.Ot === 'notRequired' ||
        btn.Ot === 'requiredSgl' ||
        (btn.Ot === 'requiredOnce' && btn.OpenType !== 'pop')
        btn.Ot === 'requiredOnce'
      ) {
        // 创建凭证时,需要选择行时
@@ -1116,23 +1117,20 @@
          func: 'sPC_TableData_InUpDe',
          BID: this.props.BID
        }
        let primaryId = setting.primaryKey && data[0] ? (data[0][setting.primaryKey] || '') : ''
        let primaryId = ''
        if (btn.Ot === 'requiredSgl' || btn.Ot === 'requiredOnce') {
          let ids = data.map(d => { return d[setting.primaryKey] || ''})
          ids = ids.filter(Boolean)
          primaryId = ids.join(',')
        }
        if (btn.OpenType === 'prompt' || btn.OpenType === 'exec') { // 是否弹框或直接执行
          let ID = ''
          if (btn.Ot === 'notRequired') {
          } else if (btn.Ot === 'requiredSgl') {
            ID = data[0][setting.primaryKey]
          } else if (btn.Ot === 'requiredOnce') { // id值拼接
            let ids = data.map(d => { return d[setting.primaryKey]})
            ID = ids.join(',')
          }
          if (btn.innerFunc) { // 使用自定义函数
            param.func = btn.innerFunc
            if (setting.primaryKey) { // 主键存在时,设置主键参数
              param[setting.primaryKey] = ID
              param[setting.primaryKey] = primaryId
            }
          } else if (btn.sql) {
            param.ID = primaryId
@@ -1182,7 +1180,7 @@
          }
          _resolve()
        })
      } else if (btn.Ot === 'required' || (btn.Ot === 'requiredOnce' && btn.OpenType === 'pop')) {
      } else if (btn.Ot === 'required') {
        let _formPrimaryId = ''
        if (formdata && setting.primaryKey) { // 表单中存在主键字段,主键值以表单中的值为准
          let _form = formdata.filter(_form => _form.key === setting.primaryKey)[0]
@@ -1736,6 +1734,12 @@
      if (this.props.BID) {
        param.BID = this.props.BID
      }
      if (this.props.dataManager) { // 数据权限
        param.LText = param.LText.replace(/\$@/ig, '/*')
        param.LText = param.LText.replace(/@\$/ig, '*/')
      } else {
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
      }
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
src/tabviews/zshare/dategroup/index.jsx
@@ -152,6 +152,7 @@
        value: active,
        label: card.label,
        match: '=',
        forbid: true,
        required: card.required === 'true'
      })
    }
src/tabviews/zshare/mutilform/index.jsx
@@ -122,7 +122,14 @@
      }
      if (item.supvalue) {
        item.supvalue = item.supvalue.split(',')
        let supvals = []
        item.supvalue.split(',').forEach(val => {
          supvals.push(val)
          if (/^([-]?(0|[1-9][0-9]*)(\.[0-9]+)?)$/.test(val)) {
            supvals.push(+val)
          }
        })
        item.supvalue = supvals
      }
      return item
src/tabviews/zshare/normalTable/index.scss
@@ -27,6 +27,9 @@
    .ant-table-tbody > tr.background td {
      background-color: unset!important;
    }
    .ant-table-tbody > tr td .anticon.font {
      background-color: unset;
    }
  }
  .ant-table-body {
    overflow-x: auto!important;
src/tabviews/zshare/topSearch/index.jsx
@@ -184,7 +184,7 @@
    this.state.searchlist.forEach((item, index) => {
      if (item.hidden) return
      if (item.type === 'text') { // 文本搜索
        fields.push(
          <Col span={item.ratio || 6} key={index}>
@@ -435,11 +435,12 @@
          _value = moment(values[key]).format('YYYY-MM')
        }
      } else if (this.state.style[key] === 'multiselect') {
        _value = values[key]
        _value = values[key] || []
      } else {
        _value = values[key].replace(/(^\s*|\s*$)/ig, '')
        _value = (values[key] || values[key] === 0) ? values[key] : ''
        _value = _value.replace(/(^\s*|\s*$)/ig, '')
      }
      search.push({
src/templates/comtableconfig/index.jsx
@@ -22,6 +22,7 @@
import ColumnComponent from '@/templates/sharecomponent/columncomponent'
import TabsComponent from '@/templates/sharecomponent/tabscomponent'
import ChartComponent from '@/templates/sharecomponent/chartcomponent'
import CardComponent from '@/templates/sharecomponent/cardcomponent'
import MenuForm from '@/templates/zshare/menuform'
import EditComponent from '@/templates/zshare/editcomponent'
@@ -555,7 +556,7 @@
            let deffers = delActions.map(item => {
              let _param = {
                func: 'sPC_MainMenu_Del',
                MenuID: item.card.uuid
                MenuID: item.card ? item.card.uuid : item.uuid
              }
              if (item.type === 'action') {
@@ -1396,6 +1397,16 @@
                        />
                      </Col>
                    )
                  } else if (item.chartType === 'card') {
                    return (
                      <Col span={item.width} key={item.uuid}>
                        <CardComponent
                          card={item}
                          config={config}
                          plotchange={this.updateconfig}
                        />
                      </Col>
                    )
                  } else {
                    return (
                      <Col span={item.width} key={item.uuid}>
src/templates/formtabconfig/index.jsx
@@ -631,6 +631,9 @@
            func: 's_debug_sql',
            LText: res.dataSource
          }
          param.LText = param.LText.replace(/@\$|\$@/ig, '')
          param.LText = Utils.formatOptions(param.LText)
          param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
          param.secretkey = Utils.encrypt(param.LText, param.timestamp)
@@ -1508,6 +1511,8 @@
          LText: res.dataresource
        }
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
src/templates/modalconfig/index.jsx
@@ -643,6 +643,9 @@
          func: 's_debug_sql',
          LText: res.dataSource
        }
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
src/templates/sharecomponent/actioncomponent/actionform/index.jsx
@@ -23,18 +23,7 @@
    interType: null, // 接口类型:内部、外部
    funcType: null,  // 功能类型
    position: null,  // 按钮位置
    reqOptionSgl: [{
      value: 'requiredSgl',
      text: this.props.dict['header.form.requiredSgl']
    }],
    reqOptions: [{
      value: 'notRequired',
      text: this.props.dict['header.form.notRequired']
    }, {
      value: 'requiredSgl',
      text: this.props.dict['header.form.requiredSgl']
    }],
    reqOptionsMutil: [{
    requireOptions: [{
      value: 'notRequired',
      text: this.props.dict['header.form.notRequired']
    }, {
@@ -56,6 +45,9 @@
    }, {
      value: 'update',
      text: this.props.dict['header.form.action.update']
    }, {
      value: 'audit',
      text: this.props.dict['header.form.action.audit']
    }],
    deleteOptions: [{
      value: '',
@@ -74,30 +66,15 @@
  
  UNSAFE_componentWillMount () {
    let _opentype = ''   // 打开方式
    let _intertype = ''  // 接口类型
    let _position = ''   // 按钮位置
    let _tabType = ''    // 按钮为弹窗(标签)时,标签的类型
    let _funcType = ''   // 功能按钮类型
    let _options = null  // 选项列表
    const { card } = this.props
    this.props.formlist.forEach(form => {
      if (form.key === 'OpenType') {
        if (this.props.card.execMode) { // 转换打印时打开方式
          _opentype = 'funcbutton'
        } else {
          _opentype = form.initVal
        }
      } else if (form.key === 'intertype') {
        _intertype = form.initVal
      } else if (form.key === 'position') {
        _position = form.initVal
      } else if (form.key === 'tabType') {
        _tabType = form.initVal
      } else if (form.key === 'funcType') {
        _funcType = form.initVal
      }
    })
    let _opentype = card.OpenType             // 打开方式
    let _tabType = card.tabType || 'SubTable' // 按钮为弹窗(标签)时,标签的类型
    let _options = null                       // 选项列表
    if (card.execMode) {           // 转换打印时打开方式
      _opentype = 'funcbutton'
    }
    let _tabs = this.props.tabs.filter(tab => tab.type === _tabType)
@@ -110,31 +87,31 @@
    } else if (_opentype === 'popview') {                                // 模态框标签页
      _options = ['label', 'Ot', 'OpenType', 'icon', 'class', 'position', 'tabType', 'linkTab', 'popClose']
    } else if (_opentype === 'excelOut') {    // 导入导出
      if (_intertype === 'outer') {
      if (card.intertype === 'outer') {
        _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'icon', 'class', 'execSuccess', 'execError', 'pagination', 'search']
      } else {
        _options = ['label', 'OpenType', 'intertype', 'innerFunc', 'icon', 'class', 'execSuccess', 'execError', 'pagination', 'search']
      }
    } else if (_opentype === 'excelIn') {    // 导入导出
      if (_intertype === 'outer') {
      if (card.intertype === 'outer') {
        _options = ['label', 'Ot', 'OpenType', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'icon', 'class', 'sheet', 'execSuccess', 'execError']
      } else {
        _options = ['label', 'Ot', 'OpenType', 'intertype', 'innerFunc', 'icon', 'class', 'sheet', 'execSuccess', 'execError']
      }
    } else if (_opentype === 'funcbutton') {
      if (!_funcType) {
      if (!card.funcType) {
        _options = ['label', 'OpenType', 'funcType', 'icon', 'class']
      } else if (_funcType === 'changeuser') {
      } else if (card.funcType === 'changeuser') {
        _options = ['label', 'OpenType', 'funcType', 'icon', 'class']
      } else if (_funcType === 'print') {
        if (_intertype === 'outer') {
      } else if (card.funcType === 'print') {
        if (card.intertype === 'outer') {
          _options = ['label', 'OpenType', 'funcType', 'execMode', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError']
        } else {
          _options = ['label', 'OpenType', 'funcType', 'execMode', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError']
        }
      }
    } else {
      if (_intertype === 'outer') {
      if (card.intertype === 'outer') {
        _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'sysInterface', 'interface', 'outerFunc', 'callbackFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError']
      } else {
        _options = ['label', 'position', 'OpenType', 'intertype', 'innerFunc', 'Ot', 'icon', 'class', 'execSuccess', 'execError', 'sql', 'sqlType']
@@ -142,21 +119,23 @@
    }
    this.setState({
      openType: _opentype,
      interType: _intertype,
      position: _position,
      funcType: _funcType,
      interType: card.intertype || 'inner',
      position: card.position || 'toolbar',
      funcType: card.funcType,
      formlist: this.props.formlist.map(item => {
        if (item.key === 'class') {
          item.options = btnClasses
        } else if (item.key === 'icon') {
          item.options = btnIcons
        } else if (item.key === 'Ot') {
          if (_opentype === 'innerpage' || _position === 'grid') {
            item.options = this.state.reqOptionSgl
          if (_opentype === 'innerpage' || card.position === 'grid') {
            item.options = this.state.requireOptions.filter(op => ['requiredSgl'].includes(op.value))
          } else if (['outerpage', 'blank', 'tab', 'popview', 'excelIn'].includes(_opentype)) {
            item.options = this.state.reqOptions
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
          } else if (card.sqlType === 'insert') {
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value))
          } else {
            item.options = this.state.reqOptionsMutil
            item.options = this.state.requireOptions
          }
        } else if (item.key === 'sqlType') {
          if (['prompt', 'exec'].includes(_opentype)) {
@@ -255,16 +234,16 @@
          _fieldval.intertype = this.state.interType
        } else if (item.key === 'Ot') {
          if (value === 'innerpage' || this.state.position === 'grid') {
            item.options = this.state.reqOptionSgl
            item.options = this.state.requireOptions.filter(op => ['requiredSgl'].includes(op.value))
            _fieldval.Ot = 'requiredSgl'
          } else if (['outerpage', 'blank', 'tab', 'popview'].includes(value)) {
            item.options = this.state.reqOptions
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
            _fieldval.Ot = 'requiredSgl'
          } else if (value === 'excelIn') {
            item.options = this.state.reqOptions
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
            _fieldval.Ot = 'notRequired'
          } else {
            item.options = this.state.reqOptionsMutil
            item.options = this.state.requireOptions
          }
        } else if (item.key === 'sqlType') {
          if (['prompt', 'exec'].includes(value)) {
@@ -282,6 +261,14 @@
        openType: value,
        formlist: _formlist
      }, () => {
        if (value === 'excelIn') {
          _fieldval.label = this.props.dict['header.form.excelIn']
          _fieldval.class = 'border-dgreen'
        } else if (value === 'excelOut') {
          _fieldval.label = this.props.dict['header.form.excelOut']
          _fieldval.class = 'dgreen'
        }
        this.props.form.setFieldsValue(_fieldval)
      })
    } else if (key === 'position') {
@@ -292,13 +279,13 @@
        formlist: this.state.formlist.map(item => {
          if (item.key === 'Ot') {
            if (this.state.openType === 'innerpage' || value === 'grid') {
              item.options = this.state.reqOptionSgl
              item.options = this.state.requireOptions.filter(op => ['requiredSgl'].includes(op.value))
              _fieldval.Ot = 'requiredSgl'
            } else if (['outerpage', 'blank', 'tab', 'popview'].includes(this.state.openType)) {
              item.options = this.state.reqOptions
              item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl'].includes(op.value))
              _fieldval.Ot = 'requiredSgl'
            } else {
              item.options = this.state.reqOptionsMutil
              item.options = this.state.requireOptions
            }
          }
          return item
@@ -347,11 +334,43 @@
          if (item.hidden) return item
          if (item.key === 'Ot' && value === 'print') {
            item.options = this.state.reqOptionsMutil
            item.options = this.state.requireOptions
          }
          return item
        })
      })
    } else if (key === 'sqlType') {
      let _fieldval = {}
      this.setState({
        formlist: this.state.formlist.map(item => {
          if (item.key === 'Ot' && value === 'insert') {
            item.options = this.state.requireOptions.filter(op => ['notRequired', 'requiredSgl', 'required'].includes(op.value))
          } else if (item.key === 'Ot') {
            item.options = this.state.requireOptions
          }
          return item
        })
      }, () => {
        if (value === 'insert') {
          _fieldval.label = '添加'
          _fieldval.class = 'green'
          _fieldval.Ot = 'notRequired'
        } else if (value === 'update') {
          _fieldval.label = '修改'
          _fieldval.class = 'purple'
          _fieldval.Ot = 'requiredSgl'
        } else if (value === 'audit') {
          _fieldval.label = '审核'
          _fieldval.class = 'purple'
          _fieldval.Ot = 'requiredSgl'
        } else if (value === 'LogicDelete' || value === 'delete') {
          _fieldval.label = '删除'
          _fieldval.class = 'danger'
          _fieldval.Ot = 'required'
        }
        this.props.form.setFieldsValue(_fieldval)
      })
    }
  }
@@ -359,6 +378,7 @@
  onChange = (e, key) => {
    const { openType } = this.state
    let value = e.target.value
    if (key === 'intertype') {
      let _options = null
      if (openType === 'excelOut') {
@@ -396,9 +416,15 @@
            item.readonly = false
          } else if (item.key === 'sysInterface') {
            item.initVal = 'false'
          } else if (item.key === 'Ot') {
            item.options = this.state.requireOptions
          }
          return item
        })
      }, () => {
        if (this.props.form.getFieldValue('sqlType') !== undefined) {
          this.props.form.setFieldsValue({sqlType: ''})
        }
      })
    } else if (key === 'sysInterface') {
      if (value === 'true') {
@@ -611,6 +637,12 @@
            if (values.funcType === 'print') {
              values.OpenType = values.execMode
            }
          } else if (['pop', 'prompt', 'exec'].includes(values.OpenType) && values.verify) {
            if (values.Ot === 'requiredOnce' && ['notRequired', 'requiredSgl', 'required'].includes(this.props.card.Ot)) {
              values.verify.uniques = []
            } else if (this.props.card.Ot === 'requiredOnce' && ['notRequired', 'requiredSgl', 'required'].includes(values.Ot)) {
              values.verify.uniques = []
            }
          }
          if (values.innerFunc === '' && values.sql === '') {
src/templates/sharecomponent/actioncomponent/index.jsx
@@ -805,7 +805,14 @@
    }
    this.actionFormRef.handleConfirm().then(result => {
      if (result.Ot === 'requiredOnce') {
        notification.warning({
          top: 92,
          message: '多行拼接时,不可创建接口!',
          duration: 5
        })
        return
      }
      let _menu = {
        type: type,
        MenuID: menu.MenuID,
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Tabs, Row, Col, Input, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Radio } from 'antd'
import { Form, Tabs, Row, Col, Input, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Radio, Typography } from 'antd'
import moment from 'moment'
import Api from '@/api'
@@ -13,6 +13,7 @@
const { TabPane } = Tabs
const { confirm } = Modal
const { Paragraph } = Typography
class VerifyCard extends Component {
  static propTpyes = {
@@ -145,7 +146,10 @@
      {
        title: 'SQL',
        dataIndex: 'sql',
        width: '60%'
        width: '60%',
        render: (text) => (
          <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph>
        )
      },
      {
        title: '执行位置',
src/templates/sharecomponent/cardcomponent/chartcompile/index.jsx
New file
@@ -0,0 +1,258 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Drawer, Form, Button, Col, Row, Select, Icon, Radio, Tooltip, Input, InputNumber } from 'antd'
import { getChartOptionForm } from '@/templates/zshare/formconfig'
import './index.scss'
class LineChartDrawerForm extends Component {
  static propTpyes = {
    dict: PropTypes.object,
    plot: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
  }
  state = {
    view: 'normal',
    visible: false,
    plot: null,
    formlist: null
  }
  showDrawer = () => {
    const { config, plot } = this.props
    this.setState({
      visible: true,
      plot: fromJS(plot).toJS(),
      formlist: getChartOptionForm(plot, config.columns, config.setting)
    })
  }
  onSubmit = () => {
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        this.setState({
          visible: false
        })
        this.props.plotchange(values)
      }
    })
  }
  radioChange = (e, key) => {
    const { formlist } = this.state
    let val = e.target.value
    if (key === 'datatype') {
      this.setState({
        formlist: formlist.map(item => {
          if (['Yaxis'].includes(item.key)) {
            item.hidden = val === 'statistics'
          } else if (['InfoType', 'InfoValue', 'InfoDefNumber'].includes(item.key)) {
            item.hidden = val !== 'statistics'
          }
          return item
        })
      })
    }
  }
  getFields() {
    const { formlist } = this.state
    const { getFieldDecorator } = this.props.form
    const fields = []
    if (!formlist) {
      return fields
    }
    formlist.forEach((item, index) => {
      if (item.hidden || item.forbid) return
      if (item.type === 'text') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly}/>)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.input'] + item.label + '!'
                  }
                ]
              })(<InputNumber min={item.min} max={item.max} precision={item.decimal} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'select') { // 下拉
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select mode={item.multi ? 'multiple' : ''}>
                  {item.options.map((option, index) =>
                    <Select.Option key={index} value={option.field}>
                      {option.label}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'radio') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" title={item.tooltip}>
                <Icon type="question-circle" />
                {item.label}
              </Tooltip> : item.label
            }>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Radio.Group disabled={item.readonly} onChange={(e) => this.radioChange(e, item.key)}>
                  {item.options.map(option => {
                    return (
                      <Radio key={option.value} value={option.value}>{option.text}</Radio>
                    )
                  })}
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  changeView = () => {
    let _view = this.state.view === 'normal' ? 'custom' : 'normal'
    if (_view === 'custom') {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          let _plot = {...this.state.plot, ...values}
          this.setState({
            plot: _plot,
            view: _view
          })
        }
      })
    }
    this.setState({view: _view})
  }
  render() {
    const { view } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 18 }
      }
    }
    return (
      <div className="line-chart-drawer-form">
        <Icon type="edit" onClick={this.showDrawer} />
        <Drawer
          title="图表编辑"
          className="chart-drawer-form"
          width={720}
          onClose={() => this.setState({ visible: false })}
          visible={this.state.visible}
          bodyStyle={{ paddingBottom: 80 }}
        >
          {view !== 'custom' ? <Form {...formItemLayout}>
            <Row gutter={16}>{this.getFields()}</Row>
            <Row gutter={16}>
              <Button onClick={this.changeView} style={{border: 0, boxShadow: 'unset',float: 'right', color: '#1890ff', marginRight: 12, cursor: 'pointer'}}>自定义设置<Icon style={{marginLeft: 5}} type="right" /></Button>
            </Row>
          </Form> : null}
          {/* <Form {...formItemLayout}>
            <Row gutter={16}>
              <Button onClick={this.changeView} style={{border: 0, boxShadow: 'unset',float: 'right', color: '#1890ff', marginRight: 12, cursor: 'pointer'}}>自定义设置<Icon style={{marginLeft: 5}} type="right" /></Button>
            </Row>
          </Form> */}
          <div
            style={{
              position: 'absolute',
              right: 0,
              bottom: 0,
              width: '100%',
              borderTop: '1px solid #e9e9e9',
              padding: '10px 16px',
              background: '#fff',
              textAlign: 'right',
            }}
          >
            <Button onClick={() => this.setState({ visible: false })} style={{ marginRight: 8 }}>
              取消
            </Button>
            <Button onClick={() => this.onSubmit()} type="primary">
              提交
            </Button>
          </div>
        </Drawer>
      </div>
    );
  }
}
export default Form.create()(LineChartDrawerForm)
src/templates/sharecomponent/cardcomponent/chartcompile/index.scss
New file
@@ -0,0 +1,40 @@
.line-chart-drawer-form {
  position: absolute;
  right: 10px;
  top: 50px;
  > .anticon-edit {
    color: #1890ff;
    font-size: 16px;
    margin-right: 5px;
  }
}
.chart-drawer-form {
  .ant-drawer-body {
    max-height: calc(100vh - 60px);
    overflow-y: auto;
    .anticon-question-circle {
      color: #c49f47;
      margin-right: 3px;
    }
    .ant-input-number {
      width: 100%;
    }
  }
  .ant-drawer-body::-webkit-scrollbar {
    width: 7px;
  }
  .ant-drawer-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-drawer-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/templates/sharecomponent/cardcomponent/dragdetail/card.jsx
New file
@@ -0,0 +1,45 @@
import React from 'react'
import { useDrag, useDrop } from 'react-dnd'
import { Icon } from 'antd'
import './index.scss'
const Card = ({ id, card, moveCard, findCard, editCard, delCard }) => {
  const originalIndex = findCard(id).index
  const [{ isDragging }, drag] = useDrag({
    item: { type: 'detail', id, originalIndex },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const opacity = isDragging ? 0 : 1
  const [, drop] = useDrop({
    accept: 'detail',
    canDrop: () => true,
    hover({ id: draggedId }) {
      if (!draggedId) return
      if (draggedId !== id) {
        const { index: overIndex } = findCard(id)
        moveCard(draggedId, overIndex)
      }
    }
  })
  let _class = ''
  if (card.type === 'title') {
    _class = 'ant-card-meta-title'
  } else {
    _class = 'ant-card-meta-description'
  }
  return (
    <div ref={node => drag(drop(node))} className={_class} style={{ opacity: opacity}}>
      <div className="content">{card.content}</div>
      <Icon className="edit" title="编辑" type="edit" onClick={() => editCard(card)} />
      <Icon className="edit close" title="删除" type="close" onClick={() => delCard(card)} />
    </div>
  )
}
export default Card
src/templates/sharecomponent/cardcomponent/dragdetail/index.jsx
New file
@@ -0,0 +1,49 @@
import React, { useState } from 'react'
import { useDrop } from 'react-dnd'
import { is, fromJS } from 'immutable'
import update from 'immutability-helper'
import Card from './card'
import './index.scss'
const Container = ({list, handleList, handleMenu, deleteMenu }) => {
  const [cards, setCards] = useState(list)
  const moveCard = (id, atIndex) => {
    const { card, index } = findCard(id)
    const _cards = update(cards, { $splice: [[index, 1], [atIndex, 0, card]] })
    handleList(_cards)
  }
  if (!is(fromJS(cards), fromJS(list))) {
    setCards(list)
  }
  const findCard = id => {
    const card = cards.filter(c => `${c.uuid}` === id)[0]
    return {
      card,
      index: cards.indexOf(card),
    }
  }
  const [, drop] = useDrop({
    accept: 'detail'
  })
  return (
    <div ref={drop} className="ant-card-meta-detail">
      {cards.map(card => (
        <Card
          key={card.uuid}
          id={card.uuid}
          card={card}
          moveCard={moveCard}
          editCard={handleMenu}
          delCard={deleteMenu}
          findCard={findCard}
        />
      ))}
    </div>
  )
}
export default Container
src/templates/sharecomponent/cardcomponent/dragdetail/index.scss
New file
@@ -0,0 +1,36 @@
.ant-card-meta-detail {
  overflow: visible;
  .ant-card-meta-title, .ant-card-meta-description {
    position: relative;
    overflow: visible;
  }
  .ant-card-meta-description {
    display: inline-block;
    width: 100%;
    vertical-align: top;
    .content {
      overflow: hidden;
      word-break: break-word;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
  }
  .edit {
    position: absolute;
    left: 0;
    top: -10px;
    font-size: 14px;
    color: #1890ff;
    cursor: pointer;
    display: none;
  }
  .edit.close {
    left: 20px;
    color: #ff4d4f;
  }
  .ant-card-meta-title:hover .edit, .ant-card-meta-description:hover .edit {
    display: inline-block;
  }
}
src/templates/sharecomponent/cardcomponent/index.jsx
New file
@@ -0,0 +1,118 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Card, Icon } from 'antd'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/model.js'
import enUS from '@/locales/en-US/model.js'
// import ChartCompileForm from './chartcompile'
import DragDetail from './dragdetail'
import './index.scss'
// const { Meta } = Card
class LineChart extends Component {
  static propTpyes = {
    card: PropTypes.object,
    config: PropTypes.object,
    plotchange: PropTypes.func
  }
  state = {
    dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
    visible: true,
    cardcell: null   // 卡片元素
  }
  componentDidMount () {
  }
  UNSAFE_componentWillReceiveProps (nextProps) {
    if (!is(fromJS(this.props.card), fromJS(nextProps.card))) {
    }
  }
  plotChange = (values) => {
    const { card, config } = this.props
    let _card = {...card, ...values}
    let _charts = fromJS(config.charts).toJS()
    _charts = _charts.map(item => {
      if (item.uuid === _card.uuid) {
        return _card
      }
      return item
    })
    this.props.plotchange({...config, charts: _charts})
  }
  handleList = (list) => {
    this.plotChange({details: list})
  }
  editdetail = (_cell) => {
    if (!_cell) {
      _cell = {uuid: Utils.getuuid()}
    }
    this.setState({
      cardcell: _cell
    })
  }
  deletedetail = () => {
  }
  render() {
    const { card } = this.props
    return (
      <div className="line-card-edit-box">
        {card.title ? <p className="chart-title">{card.title}</p> : null}
        {card.cardType === 'card1' ? <Card
          className={card.widthType === 'ratio' ? 'ant-col ant-col-' + card.cardWidth : ''}
          style={card.widthType === 'absolute' ? { width: card.cardWidth } : null}
        >
          <div className="ant-card-meta">
            <Icon type="plus" onClick={this.editdetail} />
            <DragDetail
              list={card.details}
              handleList={this.handleList}
              handleMenu={this.editdetail}
              deleteMenu={this.deletedetail}
            />
          </div>
        </Card> : null}
        {/* <Card
          className={card.widthType === 'ratio' ? 'ant-col ant-col-' + card.cardWidth : ''}
          style={card.widthType === 'absolute' ? { width: card.cardWidth } : null}
        >
          <Meta
            avatar={
              <Avatar size={64} src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
            }
            title="Card title"
            description="This is the description"
          />
        </Card> */}
        {/* <ChartCompileForm
          plot={plot}
          type={plot.chartType}
          config={this.props.config}
          dict={this.state.dict}
          plotchange={this.plotChange}
        /> */}
      </div>
    )
  }
}
export default LineChart
src/templates/sharecomponent/cardcomponent/index.scss
New file
@@ -0,0 +1,23 @@
.line-card-edit-box {
  margin-bottom: 30px;
  padding: 30px 20px;
  .ant-card {
    min-height: 100px;
  }
  .ant-card.ant-card-bordered .ant-card-body {
    padding: 20px;
    zoom: 1;
    // .ant-card-meta-avatar {
    // }
  }
  .chart-title {
    margin-bottom: 10px;
    margin-left: 0px;
    margin-right: 0px;
  }
}
src/templates/sharecomponent/chartgroupcomponent/chartform/index.jsx
@@ -103,6 +103,18 @@
        shape: 'ring'
      }
    }
  ],
  card: [
    {
      uuid: 'card1',
      url: pie1,
      type: 'card1'
    },
    {
      uuid: 'card2',
      url: pie2,
      type: 'card2'
    }
  ]
}
@@ -123,6 +135,7 @@
  UNSAFE_componentWillMount () {
    const { card } = this.props
    let formlist = JSON.parse(JSON.stringify(this.props.formlist))
    let _type = card.chartType || 'line'
    let _legends = null
@@ -135,11 +148,30 @@
      if (!_selectlegend) {
        _selectlegend = _legends[0]
      }
    } else if (_type === 'card') {
      _legends = syslegends[_type]
      _selectlegend = _legends.filter(item => item.uuid === card.cardType)[0]
      if (!_selectlegend) {
        _selectlegend = _legends[0]
      }
    }
    this.setState({
      legends: _legends,
      selectlegend: _selectlegend
      selectlegend: _selectlegend,
      formlist: formlist.map(item => {
        if (item.key === 'height' && ['table', 'card'].includes(_type)) {
          item.hidden = true
        } else if (item.key === 'widthType' && _type === 'card') {
          item.hidden = false
        } else if (item.key === 'cardWidth' && _type === 'card') {
          item.hidden = false
        } else if (item.key === 'over' && _type === 'card') {
          item.hidden = false
        }
        return item
      })
    })
  }
@@ -165,10 +197,44 @@
  }
  typeChange = (key, value) => {
    const { card } = this.props
    let formlist = JSON.parse(JSON.stringify(this.props.formlist))
    if (key === 'chartType') {
      this.setState({
        legends: syslegends[value] || null,
        selectlegend: syslegends[value][0]
        selectlegend: syslegends[value] ? syslegends[value][0] : null,
        formlist: formlist.map(item => {
          if (item.key === 'height' && ['table', 'card'].includes(value)) {
            item.hidden = true
          } else if (item.key === 'widthType' && value === 'card') {
            item.hidden = false
          } else if (item.key === 'cardWidth' && value === 'card') {
            item.min = card.widthType === 'absolute' ? 50 : 1
            item.max = card.widthType === 'absolute' ? 1000 : 24
            item.hidden = false
          } else if (item.key === 'over' && value === 'card') {
            item.hidden = false
          }
          return item
        })
      })
    }
  }
  radioChange = (val, key) => {
    const { formlist } = this.state
    if (key === 'widthType') {
      this.setState({
        formlist: formlist.map(item => {
          if (item.key === 'cardWidth') {
            item.min = val === 'absolute' ? 50 : 1
            item.max = val === 'absolute' ? 1000 : 24
          }
          return item
        })
      })
    }
  }
@@ -182,7 +248,7 @@
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.props.formlist.forEach((item, index) => {
    this.state.formlist.forEach((item, index) => {
      if (item.hidden) return
      
      if (item.type === 'text') { // 文本搜索
@@ -274,7 +340,7 @@
                  }
                ]
              })(
                <Radio.Group>
                <Radio.Group onChange={(e) => this.radioChange(e.target.value, item.key)}>
                  {
                    item.options.map(option => {
                      return (
@@ -324,21 +390,33 @@
            table: 'table',
            line: 'line-chart',
            bar: 'bar-chart',
            pie: 'pie-chart'
            pie: 'pie-chart',
            card: 'credit-card'
          }
          if (selectlegend && this.props.card.modelId !== selectlegend.uuid) {
            result = {...result, ...selectlegend.options}
          }
          if (result.chartType === 'line' || result.chartType === 'bar' || result.chartType === 'line') {
            if (selectlegend && this.props.card.modelId !== selectlegend.uuid) {
              result = {...result, ...selectlegend.options}
            }
            if (selectlegend) {
              result.modelId = selectlegend.uuid
            }
            if (result.chartType !== 'pie' && result.Yaxis && typeof(result.Yaxis) === 'string') {
              result.Yaxis = [result.Yaxis]
            } else if (result.chartType === 'pie' && result.Yaxis && typeof(result.Yaxis) === 'object') {
              result.Yaxis = result.Yaxis[0] || ''
            }
          } else if (result.chartType === 'card') {
            result.cardType = selectlegend.type
          if (selectlegend) {
            result.modelId = selectlegend.uuid
          }
          if (result.chartType !== 'pie' && result.Yaxis && typeof(result.Yaxis) === 'string') {
            result.Yaxis = [result.Yaxis]
          } else if (result.chartType === 'pie' && result.Yaxis && typeof(result.Yaxis) === 'object') {
            result.Yaxis = result.Yaxis[0] || ''
            if (!result.details) {
              result.details = [
                {type: 'title', uuid: 'cardtitle', content: 'Card title', datatype: 'static', align: 'left'},
                {type: 'description', uuid: 'carddescription', content: 'This is the description', datatype: 'static', align: 'left'}
              ]
            }
          }
          result.icon = icons[result.chartType]
src/templates/sharecomponent/chartgroupcomponent/index.jsx
@@ -219,7 +219,7 @@
        <Modal
          title={modaltype === 'addChart' ? '图表-添加' : '图标-编辑'}
          visible={modaltype === 'addChart' || modaltype === 'editChart'}
          width={750}
          width={800}
          maskClosable={false}
          onOk={this.submitChart}
          onCancel={this.editModalCancel}
src/templates/sharecomponent/searchcomponent/index.jsx
@@ -195,6 +195,9 @@
          func: 's_debug_sql',
          LText: res.dataSource
        }
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        param.LText = Utils.formatOptions(param.LText)
        param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
        param.secretkey = Utils.encrypt(param.LText, param.timestamp)
src/templates/sharecomponent/settingcomponent/settingform/customscript/index.jsx
@@ -27,15 +27,22 @@
  UNSAFE_componentWillMount() {
    const { searches } = this.props
    let _usefulFields = searches.map(item => {
    let _usefulFields = []
    searches.forEach(item => {
      if (item.type === 'group') {
        if (item.transfer === 'true') {
          return item.field + ', ' + item.datefield
        } else {
          return item.datefield
          _usefulFields.push(item.field)
        }
        _usefulFields.push(item.datefield)
        _usefulFields.push(item.datefield + '1')
      } else if (['dateweek', 'datemonth', 'daterange'].includes(item.type)) {
        _usefulFields.push(item.field)
        _usefulFields.push(item.field + '1')
      } else if (_usefulFields.includes(item.field)) {
        _usefulFields.push(item.field + '1')
      } else {
        return item.field
        _usefulFields.push(item.field)
      }
    })
@@ -124,6 +131,8 @@
          LText: _initsql + values.sql + tail
        }
        param.LText = param.LText.replace(/@\$|\$@/ig, '')
        let allSearch = Utils.initMainSearch(searches)
        allSearch = Utils.getAllSearchOptions(allSearch)
src/templates/sharecomponent/settingcomponent/settingform/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Row, Col, Input, Radio, Select, Tooltip, Icon, notification, InputNumber, Modal, Button, Table, Popconfirm } from 'antd'
import { Form, Row, Col, Input, Radio, Select, Tooltip, Icon, notification, InputNumber, Modal, Table, Popconfirm, Typography } from 'antd'
import moment from 'moment'
import Api from '@/api'
@@ -11,6 +11,7 @@
const { TextArea } = Input
const { confirm } = Modal
const { Paragraph } = Typography
class SettingForm extends Component {
  static propTpyes = {
@@ -34,7 +35,10 @@
      {
        title: 'SQL',
        dataIndex: 'sql',
        width: '60%'
        width: '60%',
        render: (text) => (
          <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph>
        )
      },
      {
        title: '初始化sql',
@@ -164,7 +168,7 @@
  }
  handleConfirm = (otype) => {
    const { menu, config, type } = this.props
    const { menu, type } = this.props
    const { view, setting } = this.state
    // 表单提交时检查输入值是否正确
@@ -180,15 +184,15 @@
            values = {...setting, ...values}
            // 数据源前端验证
            if (values.interType === 'inner' && !values.innerFunc && !values.dataresource) {
            if (values.interType === 'inner' && !values.innerFunc && values.default !== 'false' && !values.dataresource) {
              notification.warning({
                top: 92,
                message: '请自定义函数或填写数据源!',
                message: '请填写内部函数或数据源!',
                duration: 5
              })
              reject()
              return
            } else {
            } else if (values.interType === 'inner') {
              let error = Utils.verifySql(values.dataresource)
  
              if (error) {
@@ -197,6 +201,7 @@
                  message: '数据源中不可使用' + error,
                  duration: 5
                })
                reject()
                return
              }
            }
@@ -220,85 +225,14 @@
              Api.getLocalConfig(param)
            }
            // 合成自定义script
            let _customScript = ''
            values.scripts.forEach(item => {
              if (item.status === 'false' || item.initsql !== 'true') return
              _customScript += `
                ${item.sql}
              `
            })
            values.scripts.forEach(item => {
              if (item.status === 'false' || item.initsql === 'true') return
              _customScript += `
                ${item.sql}
              `
            })
            values.customScript = _customScript
            // 数据源后台语法验证
            if (values.interType === 'inner' && !values.innerFunc && /\s/.test(values.dataresource)) {
              if (otype === 'change') { // 切换自定义设置
                this.setState({
                  sqlVerifing: true
                })
              }
              let _dataresource = values.dataresource
              if (values.queryType === 'statistics') {
                let allSearch = Utils.initMainSearch(config.search)
                allSearch = Utils.getAllSearchOptions(allSearch)
                let options = allSearch.map(item => {
                  return {
                    reg: new RegExp('@' + item.key + '@', 'ig'),
                    value: item.value
                  }
                })
                options.forEach(item => {
                  _dataresource = _dataresource.replace(item.reg, `'${item.value}'`)
                })
              }
              let param = {
                func: 's_debug_sql',
                LText: _dataresource
              }
              param.LText = Utils.formatOptions(param.LText)
              param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
              param.secretkey = Utils.encrypt(param.LText, param.timestamp)
              Api.getLocalConfig(param).then(result => {
                if (result.status) {
                  if (otype === 'change') {
                    this.setState({
                      sqlVerifing: false,
                      setting: values
                    }, () => {
                      resolve()
                    })
                  } else {
                    resolve(values)
                  }
                } else {
                  this.setState({sqlVerifing: false})
                  Modal.error({
                    title: result.message
                  })
                }
              })
            } else if (otype === 'change') {
            if (otype === 'change') {
              this.setState({
                setting: values,
              }, () => {
                resolve()
              })
            } else {
              resolve(values)
              this.sqlverify(values, resolve, reject)
            }
          } else {
            reject(err)
@@ -328,6 +262,7 @@
      })
      _setting.customScript = _customScript
      let _this = this
      return new Promise((resolve, reject) => {
        if (_loading) {
@@ -336,16 +271,87 @@
            okText: this.props.dict['model.confirm'],
            cancelText: this.props.dict['header.cancel'],
            onOk() {
              resolve(_setting)
              _this.sqlverify(_setting, resolve, reject)
            },
            onCancel() {
              reject()
            }
          })
        } else {
          resolve(_setting)
          this.sqlverify(_setting, resolve, reject)
        }
      })
    }
  }
  sqlverify = (_setting, _resolve, _reject) => {
    const { config } = this.props
    if (_setting.interType === 'inner' && !_setting.innerFunc && _setting.default !== 'false' && /\s/.test(_setting.dataresource)) {
      let _dataresource = _setting.dataresource
      let _customScript = _setting.customScript
      let allSearch = Utils.initMainSearch(config.search)
      allSearch = Utils.getAllSearchOptions(allSearch)
      let regoptions = allSearch.map(item => {
        return {
          reg: new RegExp('@' + item.key + '@', 'ig'),
          value: `'${item.value}'`
        }
      })
      if (_setting.queryType === 'statistics') {
        regoptions.forEach(item => {
          _dataresource = _dataresource.replace(item.reg, item.value)
        })
      }
      if (_customScript) {
        regoptions.push({
          reg: new RegExp('@orderBy@', 'ig'),
          value: _setting.order
        })
        if (_setting.laypage !== 'false') {
          regoptions.push({
            reg: new RegExp('@pageSize@', 'ig'),
            value: 10
          }, {
            reg: new RegExp('@pageIndex@', 'ig'),
            value: 1
          })
        }
        regoptions.forEach(item => {
          _customScript = _customScript.replace(item.reg, item.value)
        })
        _dataresource = `${_customScript}
          ${_dataresource}
        `
      }
      _dataresource = _dataresource.replace(/@\$|\$@/ig, '')
      let param = {
        func: 's_debug_sql',
        LText: _dataresource
      }
      param.LText = Utils.formatOptions(param.LText)
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
      Api.getLocalConfig(param).then(result => {
        if (result.status) {
          _resolve(_setting)
        } else {
          _reject()
          Modal.error({
            title: result.message
          })
        }
      })
    } else {
      _resolve(_setting)
    }
  }
@@ -445,6 +451,7 @@
  changeView = () => {
    const { view } = this.state
    let _this = this
    if (view === 'normal') {
      this.handleConfirm('change').then(() => {
@@ -509,12 +516,9 @@
        })
        this.scrolltop()
      }, () => {
        this.setState({sqlVerifing: false})
      })
    } else {
      let _loading = false
      let _this = this
      if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql')) {
        _loading = true
@@ -535,11 +539,11 @@
          onCancel() {}
        })
      } else {
        this.setState({
        _this.setState({
          view: 'normal'
        })
        this.scrolltop()
        _this.scrolltop()
      }
    }
  }
@@ -856,7 +860,7 @@
        <Form {...formItemLayout} className="model-table-setting-form" id="model-table-setting-form">
          {view !=='custom' ? <Row gutter={24}>{this.getFields(formlist)}</Row> : null}
          <Row gutter={24}>
            {view !=='custom' ? <Button loading={this.state.sqlVerifing} onClick={this.changeView} style={{border: 0, boxShadow: 'unset',float: 'right', color: '#1890ff', marginRight: 12, cursor: 'pointer'}}>自定义设置<Icon style={{marginLeft: 5}} type="right" /></Button> : null}
            {view !=='custom' ? <span onClick={this.changeView} style={{float: 'right', color: '#1890ff', marginRight: 12, marginTop: 15, cursor: 'pointer'}}>自定义设置<Icon style={{marginLeft: 5}} type="right" /></span> : null}
            {view ==='custom' ? <span onClick={this.changeView} style={{float: 'left', color: '#1890ff', marginLeft: 12, marginTop: 15, cursor: 'pointer'}}><Icon style={{marginRight: 5}} type="left" />基础设置</span> : null}
          </Row>
        </Form>
src/templates/zshare/formconfig.jsx
@@ -689,20 +689,62 @@
  return [
    {
      type: 'text',
      key: 'label',
      label: Formdict['header.form.name'],
      initVal: card.label,
      required: true,
      readonly: false
    },
    {
      type: 'select',
      key: 'OpenType',
      label: Formdict['header.form.openType'],
      initVal: card.OpenType,
      required: true,
      options: opentypes
    },
    {
      type: 'radio',
      key: 'intertype',
      label: Formdict['header.form.intertype'],
      initVal: card.intertype || 'inner',
      required: true,
      options: [{
        value: 'inner',
        text: Formdict['header.form.interface.inner']
      }, {
        value: 'outer',
        text: Formdict['header.form.interface.outer']
      }]
    },
    {
      type: 'select',
      key: 'sqlType',
      label: Formdict['header.form.action.type'],
      initVal: card.sqlType || '',
      tooltip: Formdict['header.form.actionhelp.sqlType'],
      required: false,
      options: []
    },
    {
      type: 'text',
      key: 'label',
      label: '按钮名称',
      initVal: card.label,
      required: true,
      readonly: false
    },
    {
      type: 'text',
      key: 'sql',
      label: Formdict['header.form.tablename'],
      initVal: card.sql || config.setting.tableName || '',
      tooltip: Formdict['header.form.actionhelp.tablename'],
      required: false
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: Formdict['header.form.innerFunc'],
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: permFuncField,
      tooltipClass: 'middle',
      required: false,
      readonly: false
    },
    {
      type: 'select',
@@ -771,31 +813,6 @@
      label: Formdict['header.form.newpage.url'],
      initVal: card.url || '',
      required: true
    },
    {
      type: 'radio',
      key: 'intertype',
      label: Formdict['header.form.intertype'],
      initVal: card.intertype || 'inner',
      required: true,
      options: [{
        value: 'inner',
        text: Formdict['header.form.interface.inner']
      }, {
        value: 'outer',
        text: Formdict['header.form.interface.outer']
      }]
    },
    {
      type: 'text',
      key: 'innerFunc',
      label: Formdict['header.form.innerFunc'],
      initVal: card.innerFunc || '',
      tooltip: functip,
      fields: permFuncField,
      tooltipClass: 'middle',
      required: false,
      readonly: false
    },
    {
      type: 'radio',
@@ -969,23 +986,6 @@
      label: Formdict['header.form.tablename'],
      initVal: card.sheet || config.setting.tableName || '',
      required: true
    },
    {
      type: 'text',
      key: 'sql',
      label: Formdict['header.form.tablename'],
      initVal: card.sql || config.setting.tableName || '',
      tooltip: Formdict['header.form.actionhelp.tablename'],
      required: false
    },
    {
      type: 'select',
      key: 'sqlType',
      label: Formdict['header.form.action.type'],
      initVal: card.sqlType || '',
      tooltip: Formdict['header.form.actionhelp.sqlType'],
      required: false,
      options: []
    },
    {
      type: 'radio',
@@ -1227,6 +1227,9 @@
  }, {
    value: 'pie',
    text: '饼图'
  }, {
    value: 'card',
    text: '卡片'
  }]
  if (card.chartType === 'table') {
@@ -1289,6 +1292,48 @@
      }]
    },
    {
      type: 'radio',
      key: 'widthType',
      label: '宽度类型',
      initVal: card.widthType || 'ratio',
      required: true,
      hidden: true,
      options: [{
        value: 'ratio',
        text: '比例'
      }, {
        value: 'absolute',
        text: '绝对值'
      }]
    },
    {
      type: 'number',
      key: 'cardWidth',
      min: card.widthType === 'absolute' ? 50 : 1,
      max: card.widthType === 'absolute' ? 1000 : 24,
      decimal: 0,
      label: '卡片宽度',
      tooltip: '类型为比例时,范围1-24,24即为100%;类型为绝对值,范围50-1000。',
      initVal: card.cardWidth || 6,
      hidden: true,
      required: true
    },
    {
      type: 'radio',
      key: 'over',
      label: '超出时',
      initVal: card.over || 'roll',
      required: true,
      hidden: true,
      options: [{
        value: 'whole',
        text: '展示全部'
      }, {
        value: 'roll',
        text: '滚动'
      }]
    },
    {
      type: 'multiselect',
      key: 'blacklist',
      label: Formdict['header.form.blacklist'],
src/templates/zshare/verifycard/index.jsx
@@ -1,6 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Tabs, Row, Col, Radio, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Tooltip } from 'antd'
import { fromJS } from 'immutable'
import { Form, Tabs, Row, Col, Radio, Button, Table, Popconfirm, Icon, notification, Modal, message, InputNumber, Tooltip, Typography } from 'antd'
import moment from 'moment'
import Api from '@/api'
@@ -13,10 +14,10 @@
import BillcodeForm from './billcodeform'
import VoucherForm from './voucherform'
import './index.scss'
import { fromJS } from 'immutable';
const { TabPane } = Tabs
const { confirm } = Modal
const { Paragraph } = Typography
class VerifyCard extends Component {
  static propTpyes = {
@@ -166,7 +167,10 @@
      {
        title: 'SQL',
        dataIndex: 'sql',
        width: '45%'
        width: '45%',
        render: (text) => (
          <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph>
        )
      },
      {
        title: '结果处理',
@@ -227,7 +231,10 @@
      {
        title: 'SQL',
        dataIndex: 'sql',
        width: '60%'
        width: '60%',
        render: (text) => (
          <Paragraph copyable ellipsis={{ rows: 5, expandable: true }}>{text}</Paragraph>
        )
      },
      {
        title: '执行位置',
@@ -521,7 +528,7 @@
        if (config.setting.primaryKey && !keys.includes(config.setting.primaryKey.toLowerCase())) {
          keys.push(config.setting.primaryKey.toLowerCase())
          values.push('\'\'')
          values.push('@ID@')
        }
        if (!keys.includes('createuserid')) {
          keys.push('createuserid')
@@ -540,8 +547,8 @@
          values.push('@BID@')
        }
  
        keys = keys.join(',')
        values = values.join(',')
        keys = keys.join(', ')
        values = values.join(', ')
        _insertsql = `insert into ${this.props.card.sql} (${keys}) select ${values};`
      }
      
@@ -574,14 +581,9 @@
            _form.push('FiYear=@FiYear')
          }
        }
        let primaryKeyName = config.setting.primaryKey
        if (primaryKeyName && ['id', 'bid', 'loginuid', 'sessionuid', 'userid', 'appkey'].includes(primaryKeyName.toLowerCase())) {
          primaryKeyName = primaryKeyName + '@'
        }
        _form = _form.join(',')
        _updatesql = `update ${this.props.card.sql} set ${_form} where ${config.setting.primaryKey}=@${primaryKeyName};`
        _form = _form.join(', ')
        _updatesql = `update ${this.props.card.sql} set ${_form} where ${config.setting.primaryKey}=@ID@;`
      }
      let _defaultsql = ''
@@ -764,7 +766,7 @@
            if (config.setting.primaryKey && !keys.includes(config.setting.primaryKey.toLowerCase())) {
              keys.push(config.setting.primaryKey.toLowerCase())
              values.push('\'\'')
              values.push('@ID@')
            }
            if (!keys.includes('createuserid')) {
              keys.push('createuserid')
@@ -783,10 +785,10 @@
              values.push('@BID@')
            }
      
            keys = keys.join(',')
            values = values.join(',')
            keys = keys.join(', ')
            values = values.join(', ')
            _defaultsql = `insert into ${this.props.card.sql} (${keys}) select ${values};`
          } else if (this.props.card.sqlType === 'update') {
          } else if (this.props.card.sqlType === 'update' || this.props.card.sqlType === 'audit') {
            let _form = []
            let _arr = []
@@ -797,11 +799,20 @@
              _form.push(item.field + '=@' + item.field)
            })
            if (!_arr.includes('modifydate')) {
              _form.push('modifydate=getdate()')
            }
            if (!_arr.includes('modifyuserid')) {
              _form.push('modifyuserid=@userid@')
            if (this.props.card.sqlType === 'audit') {
              if (!_arr.includes('submitdate')) {
                _form.push('submitdate=getdate()')
              }
              if (!_arr.includes('submituserid')) {
                _form.push('submituserid=@userid@')
              }
            } else {
              if (!_arr.includes('modifydate')) {
                _form.push('modifydate=getdate()')
              }
              if (!_arr.includes('modifyuserid')) {
                _form.push('modifyuserid=@userid@')
              }
            }
            if (_verify.voucher && _verify.voucher.enabled) {
@@ -815,14 +826,9 @@
                _form.push('FiYear=@FiYear')
              }
            }
            let primaryKeyName = config.setting.primaryKey
            if (primaryKeyName && ['id', 'bid', 'loginuid', 'sessionuid', 'userid', 'appkey'].includes(primaryKeyName.toLowerCase())) {
              primaryKeyName = primaryKeyName + '@'
            }
            _form = _form.join(',')
            _defaultsql = `update ${this.props.card.sql} set ${_form} where ${config.setting.primaryKey}=@${primaryKeyName};`
            _form = _form.join(', ')
            _defaultsql = `update ${this.props.card.sql} set ${_form} where ${config.setting.primaryKey}=@ID@;`
          }
          
          this.setState({
@@ -891,14 +897,9 @@
      // 默认sql
      let _defaultsql = ''
      let primaryKeyName = config.setting.primaryKey
      if (primaryKeyName && ['id', 'bid', 'loginuid', 'sessionuid', 'userid', 'appkey'].includes(primaryKeyName.toLowerCase())) {
        primaryKeyName = primaryKeyName + '@'
      }
      if (this.props.card.sqlType === 'LogicDelete') {
        _defaultsql = `update ${this.props.card.sql} set deleted=1,modifydate=getdate(),modifyuserid=@userid@ where ${config.setting.primaryKey}=@${primaryKeyName};`
        _defaultsql = `update ${this.props.card.sql} set deleted=1,modifydate=getdate(),modifyuserid=@userid@ where ${config.setting.primaryKey}=@ID@;`
      } else if (this.props.card.sqlType === 'delete') {
        let _msg = ''
        if (columns && columns.length > 0 && this.props.card.Ot !== 'notRequired') {
@@ -910,7 +911,7 @@
            }
          })
        }
        _defaultsql += `insert into snote (remark,createuserid,CreateUser,CreateStaff) select left('删除表:${this.props.card.sql} 数据: ${_msg}${config.setting.primaryKey}='+@${primaryKeyName},200),@userid@,@username,@fullname delete ${this.props.card.sql} where ${config.setting.primaryKey}=@${primaryKeyName};`
        _defaultsql += `insert into snote (remark,createuserid,CreateUser,CreateStaff) select left('删除表:${this.props.card.sql} 数据: ${_msg}${config.setting.primaryKey}='+@ID@,200),@userid@,@username,@fullname delete ${this.props.card.sql} where ${config.setting.primaryKey}=@ID@;`
      }
      this.setState({
@@ -1520,6 +1521,7 @@
  }
  render() {
    const { card } = this.props
    const { verify, fields, uniqueColumns, contrastColumns, customColumns, orderColumns, scriptsColumns, orderModular, orderModularDetail, voucher, voucherDetail } = this.state
    const formItemLayout = {
      labelCol: {
@@ -1533,7 +1535,7 @@
    }
    let display = false
    if (this.props.card.intertype === 'inner' && !this.props.card.innerFunc) {
    if (card.intertype === 'inner' && !card.innerFunc) {
      display = true
    }
@@ -1590,7 +1592,7 @@
              pagination={false}
            />
          </TabPane>
          <TabPane tab="唯一性验证" key="2">
          <TabPane tab={card.Ot !== 'requiredOnce' ? '唯一性验证' : '同类数据验证'} key="2">
            <UniqueForm
              fields={fields}
              dict={this.props.dict}
src/utils/option.js
@@ -213,6 +213,30 @@
}, {
  value: 'step-forward',
  text: 'step-forward'
}, {
  value: 'logout',
  text: 'logout'
}, {
  value: 'login',
  text: 'login'
}, {
  value: 'play-circle',
  text: 'play-circle'
}, {
  value: 'clock-circle',
  text: 'clock-circle'
}, {
  value: 'pause-circle',
  text: 'pause-circle'
}, {
  value: 'stop',
  text: 'stop'
}, {
  value: 'lock',
  text: 'lock'
}, {
  value: 'unlock',
  text: 'unlock'
}]
// 按钮颜色集
src/utils/utils.js
@@ -200,6 +200,7 @@
        item.value = search.initval && search.initval[0] ? search.initval[0] : ''
        item.match = '='
        item.forbid = true
        
        copy.type = 'daterange'
        copy.match = 'between'
@@ -374,7 +375,7 @@
    let searchText = ''
    searches.forEach(item => {
      if (!item.value || (item.type === 'multiselect' && item.value.length === 0)) return
      if (item.forbid || !item.value || (item.type === 'multiselect' && item.value.length === 0)) return
      
      searchText += (searchText !== '' ? ' AND ' : '')
      if (item.type === 'text') {
@@ -455,15 +456,15 @@
      if (item.type === 'date') {
        if (['>=', '>'].includes(item.match)) {
          item.value = item.value ? item.value + ' 00:00:00.000' : '1990-01-01 00:00:00.000'
          item.value = item.value ? item.value + ' 00:00:00.000' : '1970-01-01 00:00:00.000'
        } else if (['<=', '<'].includes(item.match)) {
          item.value = item.value ? moment(item.value, 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000' : '2030-01-01 00:00:00.000'
          item.value = item.value ? moment(item.value, 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000' : '2050-01-01 00:00:00.000'
        }
        options.push(item)
      } else if (item.type === 'datemonth') {
        let _startval = item.value ? moment(item.value, 'YYYY-MM').startOf('month').format('YYYY-MM-DD') + ' 00:00:00.000' : '1990-01-01 00:00:00.000'
        let _endval = item.value ? moment(item.value, 'YYYY-MM').endOf('month').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000' : '2030-01-01 00:00:00.000'
        let _startval = item.value ? moment(item.value, 'YYYY-MM').startOf('month').format('YYYY-MM-DD') + ' 00:00:00.000' : '1970-01-01 00:00:00.000'
        let _endval = item.value ? moment(item.value, 'YYYY-MM').endOf('month').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000' : '2050-01-01 00:00:00.000'
        let copy = JSON.parse(JSON.stringify(item))
        copy.key = copy.key + '1'
@@ -474,8 +475,8 @@
        options.push(item)
        options.push(copy)
      } else if (item.type === 'dateweek') {
        let _startval = item.value && item.value[0] ? moment(item.value[0], 'YYYY-MM-DD').format('YYYY-MM-DD') + ' 00:00:00.000' : '1990-01-01 00:00:00.000'
        let _endval = item.value && item.value[1] ? moment(item.value[1], 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000' : '2030-01-01 00:00:00.000'
        let _startval = item.value && item.value[0] ? moment(item.value[0], 'YYYY-MM-DD').format('YYYY-MM-DD') + ' 00:00:00.000' : '1970-01-01 00:00:00.000'
        let _endval = item.value && item.value[1] ? moment(item.value[1], 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000' : '2050-01-01 00:00:00.000'
        let copy = JSON.parse(JSON.stringify(item))
        copy.key = copy.key + '1'
@@ -486,8 +487,8 @@
        options.push(item)
        options.push(copy)
      } else if (item.type === 'daterange') {
        let _startval = item.value && item.value[0] ? item.value[0] + ' 00:00:00.000' : '1990-01-01 00:00:00.000'
        let _endval = item.value && item.value[1] ? moment(item.value[1], 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000' : '2030-01-01 00:00:00.000'
        let _startval = item.value && item.value[0] ? item.value[0] + ' 00:00:00.000' : '1970-01-01 00:00:00.000'
        let _endval = item.value && item.value[1] ? moment(item.value[1], 'YYYY-MM-DD').add(1, 'days').format('YYYY-MM-DD') + ' 00:00:00.000' : '2050-01-01 00:00:00.000'
        let copy = JSON.parse(JSON.stringify(item))
        copy.key = copy.key + '1'
@@ -938,8 +939,8 @@
      })
    }
    // 添加数据中字段,表单值优先(按钮不选行时跳过)
    if (data && btn.Ot !== 'notRequired') {
    // 添加数据中字段,表单值优先(按钮不选行或多行拼接时跳过)
    if (data && btn.Ot !== 'notRequired' && btn.Ot !== 'requiredOnce') {
      _formFieldValue = {...data, ..._formFieldValue}
      if (logcolumns && logcolumns.length > 0) {
@@ -1076,8 +1077,8 @@
      })
    }
    // 唯一性验证,必须存在表单(表单存在时,主键均为单值),必须填写数据源
    if (formdata && verify.uniques && verify.uniques.length > 0) {
    // 唯一性验证,必须存在表单(表单存在时,主键均为单值),必须填写数据源,多行拼接时不可用
    if (formdata && verify.uniques && verify.uniques.length > 0 && btn.Ot !== 'requiredOnce') {
      let hasBid = false // 检验表单及列字段中是否有bid
      let _keys_ = Object.keys(_formFieldValue).map(key => key.toLowerCase())
      if (_keys_.includes('bid')) {
@@ -1092,9 +1093,7 @@
        item.field.split(',').forEach((_field, index) => {
          let _fval = `'${_formFieldValue[_field]}'`
          // if (['id', 'bid', 'loginuid', 'sessionuid', 'userid', 'appkey'].includes(_field.toLowerCase())) {
          //   _fval = '@' + _field + '@'
          // }
          if (_field.toLowerCase() === 'bid' && !hasBid) { // 表单中没有bid则使用系统bid变量
            _fval = '@BID@'
          }
@@ -1123,6 +1122,26 @@
          goto aaa
        end
        `
      })
    } else if (verify.uniques && verify.uniques.length > 0 && btn.Ot === 'requiredOnce' && setting.dataresource) {
      let datasource = setting.dataresource
      if (/\s/.test(datasource)) { // 拼接别名
        datasource = '(' + datasource + ') tb'
      }
      verify.uniques.forEach(item => {
        console.log(item)
        // `有同类数据验证:
        // 与唯一性验证一样,可以选几个字段
        // Set @tbid=’’
        // Select top 1 @tbid=’X’ from (select 多个字段逗号分隔,主键,1 an n from 数据源 ) tb  inner join (select ID from  dbo.SplitComma(@ID@)) sp on tb.主键=sp.ID group by 多个字段逗号分隔 having sum(n)>1
        // If @tbid!=’’
        // Begin
        //     Set @errorcode=’E’ ,Set @remsg=’多个字段逗号分隔 值不唯一’ goto aaa
        // end
        // `
      })
    }
    
@@ -1226,8 +1245,6 @@
        `
    }
    let primaryKeyName = ['id', 'bid', 'loginuid', 'sessionuid', 'userid', 'appkey'].includes(primaryKey.toLowerCase()) ? primaryKey + '@' : primaryKey
    let _insertsql = ''
    if (_actionType === 'insert' || _actionType === 'insertOrUpdate') { // 添加语句
      let keys = []
@@ -1272,7 +1289,7 @@
    }
    let _updatesql = ''
    if (_actionType === 'update' || _actionType === 'insertOrUpdate') { // 修改语句
    if (_actionType === 'update' || _actionType === 'audit' || _actionType === 'insertOrUpdate') { // 修改语句
      let _form = []
      let _arr = []
@@ -1281,12 +1298,22 @@
        _form.push(item.key + '=@' + item.key)
      })
      if (!_arr.includes('modifydate')) {
        _form.push('modifydate=getdate()')
      if (_actionType === 'audit') {
        if (!_arr.includes('submitdate')) {
          _form.push('submitdate=getdate()')
        }
        if (!_arr.includes('submituserid')) {
          _form.push('submituserid=@userid@')
        }
      } else {
        if (!_arr.includes('modifydate')) {
          _form.push('modifydate=getdate()')
        }
        if (!_arr.includes('modifyuserid')) {
          _form.push('modifyuserid=@userid@')
        }
      }
      if (!_arr.includes('modifyuserid')) {
        _form.push('modifyuserid=@userid@')
      }
      if (hasvoucher) {
        if (!_arr.includes('bvoucher')) {
          _form.push('BVoucher=@BVoucher')
@@ -1299,7 +1326,13 @@
        }
      }
      _form = _form.join(',')
      _updatesql = `update ${btn.sql} set ${_form} where ${primaryKey}=@${primaryKeyName};`
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _updatesql = `update ${btn.sql} set ${_form} where ${primaryKey}${_ID};`
    }
    if (_prevCustomScript) {
@@ -1311,14 +1344,19 @@
      _sql += `
        /* 默认sql */
        ${_insertsql}`
    } else if (_actionType === 'update') {
    } else if (_actionType === 'update' || _actionType === 'audit') {
      _sql += `
        /* 默认sql */
        ${_updatesql}`
    } else if (_actionType === 'LogicDelete') { // 逻辑删除
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _sql += `
        /* 默认sql */
        update ${btn.sql} set deleted=1,modifydate=getdate(),modifyuserid=@userid@ where ${primaryKey}=@${primaryKeyName};`
        update ${btn.sql} set deleted=1,modifydate=getdate(),modifyuserid=@userid@ where ${primaryKey}${_ID};`
    
    } else if (_actionType === 'delete') {      // 物理删除
      let _msg = ''
@@ -1331,9 +1369,15 @@
          }
        })
      }
      let _ID = '=@ID@'
      if (btn.Ot === 'requiredOnce') {
        _ID = ' in (select ID from  dbo.SplitComma(@ID@))'
      }
      _sql += `
        /* 默认sql */
        insert into snote (remark,createuserid,CreateUser,CreateStaff) select left('删除表:${btn.sql} 数据: ${_msg}${primaryKey}='+@${primaryKeyName},200),@userid@,@username,@fullname delete ${btn.sql} where ${primaryKey}=@${primaryKeyName};`
        insert into snote (remark,createuserid,CreateUser,CreateStaff) select left('删除表:${btn.sql} 数据: ${_msg}${primaryKey}='+@ID@,200),@userid@,@username,@fullname delete ${btn.sql} where ${primaryKey}${_ID};`
    } else if (_actionType === 'insertOrUpdate') {
      _sql += `
        /* 默认sql */
@@ -1524,7 +1568,11 @@
    if (!_vars.includes(primaryKey.toLowerCase())) {
      _vars.push(primaryKey.toLowerCase())
      formParam = `mchr13k@${primaryKey} nvarchar(50)='',`
      let _type = '50'
      if (btn.Ot === 'requiredOnce') { // 多行拼接时,主键设为max
        _type = 'max'
      }
      formParam = `mchr13k@${primaryKey} nvarchar(${_type})='',`
    }
    if (param.fields && param.fields.length > 0) {
src/views/login/index.jsx
@@ -215,7 +215,8 @@
        let memberLevel = res.member_level
        if (typeof(memberLevel) === 'number' && memberLevel > 10) {
        if (typeof(memberLevel) === 'number' && memberLevel > 10 && parseInt(memberLevel / 10) * 10 === memberLevel) {
          sessionStorage.setItem('Member_Level', md5('mksoft' + moment().format('YYYYMM') + memberLevel))
          this.props.modifyMemberLevel(memberLevel)
        }
      } else {