king
2020-11-11 98ee5d4c76d2802c552851e46bd4bb43505b4416
2020-11-11
15个文件已修改
639 ■■■■ 已修改文件
src/locales/en-US/main.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/index.jsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcomponent/settingform/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/wrapsetting/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/wrapsetting/settingform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/settingform/index.jsx 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modelsource/option.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/billprint/index.jsx 515 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/main.js
@@ -37,6 +37,7 @@
  'main.action.primarykey.required': 'Primary key not set!',
  'main.action.primarykey.repetition': 'There are multiple primary keys!',
  'main.action.primarykey.repetitionbid': 'There are multiple BID!',
  'main.view.unenabled': '抱歉,你访问的页面未启用,请联系管理员。',
  'main.excel.line': 'line',
  'main.excel.column': 'column',
  'main.excel.includekey': ' Contain keywords ',
src/menu/components/card/cardcomponent/index.jsx
@@ -16,6 +16,7 @@
class CardBoxComponent extends Component {
  static propTpyes = {
    MenuType: PropTypes.any,         // 菜单类型
    cards: PropTypes.object,         // 卡片行配置信息
    card: PropTypes.object,          // 卡片配置信息
    deleteElement: PropTypes.func,   // 卡片删除
@@ -49,7 +50,9 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props.cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState))
    const { cards, MenuType } = this.props
    return !is(fromJS(cards), fromJS(nextProps.cards)) || !is(fromJS(this.state), fromJS(nextState)) || MenuType !== nextProps.MenuType
  }
  /**
@@ -204,7 +207,7 @@
  }
  render() {
    const { cards } = this.props
    const { cards, MenuType } = this.props
    const { card, elements, side, settingVisible, dict } = this.state
    let _style = card.style
@@ -220,11 +223,11 @@
            <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
              <div className="mk-popover-control">
                <Icon className="plus" title="添加元素" onClick={this.addElement} type="plus" />
                <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" />
                {MenuType !== 'billPrint' ? <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> : null}
                <Icon className="edit" type="edit" onClick={() => this.setState({settingVisible: true})} />
                <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
                {cards.subtype === 'propcard' ? <Icon className="close" title="删除卡片" type="delete" onClick={() => this.props.deleteElement(card)} /> : null}
                {card.setting.type === 'multi' ? <Switch size="small" onClick={this.changeSide} defaultChecked /> : null}
                {MenuType !== 'billPrint' && card.setting.type === 'multi' ? <Switch size="small" onClick={this.changeSide} defaultChecked /> : null}
              </div>
            } trigger="hover">
              <Icon type="tool" />
@@ -245,6 +248,7 @@
          <SettingForm
            dict={dict}
            cards={cards}
            MenuType={MenuType}
            setting={card.setting}
            inputSubmit={this.settingSubmit}
            wrappedComponentRef={(inst) => this.settingRef = inst}
src/menu/components/card/cardcomponent/settingform/index.jsx
@@ -6,6 +6,7 @@
class SettingForm extends Component {
  static propTpyes = {
    MenuType: PropTypes.any,     // 菜单类型
    dict: PropTypes.object,      // 字典项
    cards: PropTypes.object,     // 卡片集
    setting: PropTypes.object,   // 数据源配置
@@ -38,7 +39,7 @@
  }
  render() {
    const { setting, cards } = this.props
    const { setting, cards, MenuType } = this.props
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
@@ -74,7 +75,7 @@
                })(<InputNumber min={1} max={24} precision={0} onPressEnter={this.handleSubmit}/>)}
              </Form.Item>
            </Col>
            <Col span={12}>
            {MenuType !== 'billPrint' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择复式卡时,可配置鼠标悬浮时的显示信息。">
                  <Icon type="question-circle" />
@@ -90,8 +91,8 @@
                  </Radio.Group>
                )}
              </Form.Item>
            </Col>
            {this.state.type === 'multi' ? <Col span={12}>
            </Col> : null}
            {MenuType !== 'billPrint' && this.state.type === 'multi' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="复式卡片鼠标悬浮信息的动画效果。">
                  <Icon type="question-circle" />
src/menu/components/card/data-card/index.jsx
@@ -103,7 +103,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu)
  }
  /**
@@ -193,7 +193,7 @@
      <div className="menu-data-card-edit-box" style={{...card.style, minHeight: card.wrap.minHeight}}>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <WrapComponent sysRoles={menu ? menu.sysRoles : []} config={card} updateConfig={this.updateComponent} />
            {menu ? <WrapComponent sysRoles={menu.sysRoles} MenuType={menu.MenuType} config={card} updateConfig={this.updateComponent} /> : null}
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
            <SettingComponent config={card} updateConfig={this.updateComponent} />
@@ -201,7 +201,7 @@
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} MenuType={menu ? menu.MenuType : ''} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        {card.wrap.addable === 'true' ? <div className="card-add-button"><Icon type="plus" /></div> : null}
      </div>
    )
src/menu/components/card/data-card/wrapsetting/index.jsx
@@ -11,6 +11,7 @@
class DataSource extends Component {
  static propTpyes = {
    config: PropTypes.any,
    MenuType: PropTypes.any,
    sysRoles: PropTypes.array,
    updateConfig: PropTypes.func
  }
@@ -51,7 +52,7 @@
  }
  render () {
    const { config, sysRoles } = this.props
    const { config, sysRoles, MenuType } = this.props
    const { visible, dict, wrap } = this.state
    return (
@@ -72,6 +73,7 @@
            dict={dict}
            wrap={wrap}
            config={config}
            MenuType={MenuType}
            sysRoles={sysRoles || []}
            inputSubmit={this.verifySubmit}
            wrappedComponentRef={(inst) => this.verifyRef = inst}
src/menu/components/card/data-card/wrapsetting/settingform/index.jsx
@@ -6,6 +6,7 @@
class SettingForm extends Component {
  static propTpyes = {
    MenuType: PropTypes.any,     // 菜单类型
    sysRoles: PropTypes.array,   // 角色列表
    dict: PropTypes.object,      // 字典项
    config: PropTypes.object,    // 卡片行信息
@@ -35,7 +36,7 @@
  }
  render() {
    const { wrap, config, sysRoles } = this.props
    const { wrap, config, sysRoles, MenuType } = this.props
    const { getFieldDecorator } = this.props.form
    const formItemLayout = {
@@ -113,7 +114,7 @@
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype === 'datacard' ? <Col span={12}>
            {MenuType !== 'billPrint' && config.subtype === 'datacard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择含有添加按钮时,请完善按钮配置信息。">
                  <Icon type="question-circle" />
@@ -130,7 +131,7 @@
                )}
              </Form.Item>
            </Col> : null}
            {config.subtype !== 'tablecard' ? <Col span={12}>
            {MenuType !== 'billPrint' && config.subtype !== 'tablecard' ? <Col span={12}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择卡片切换时,可向其他组件传递主键值。">
                  <Icon type="question-circle" />
src/menu/components/card/prop-card/index.jsx
@@ -85,7 +85,7 @@
        style: { marginLeft: '0px', marginRight: '0px', marginTop: '8px', marginBottom: '8px' },
        columns: [],
        scripts: [],
        subcards: subcards
        subcards: subcards,
      }
      this.setState({
        card: _card
@@ -103,7 +103,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu)
  }
  /**
@@ -229,7 +229,7 @@
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <Icon className="plus" title="添加卡片" onClick={this.addCard} type="plus" />
            <WrapComponent config={card} sysRoles={menu ? menu.sysRoles : []} updateConfig={this.updateComponent} />
            {menu ? <WrapComponent config={card} sysRoles={menu.sysRoles} MenuType={menu.MenuType} updateConfig={this.updateComponent} /> : null}
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
@@ -237,7 +237,7 @@
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} MenuType={menu ? menu.MenuType : ''} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
      </div>
    )
  }
src/menu/components/card/table-card/index.jsx
@@ -99,7 +99,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu)
  }
  /**
@@ -262,7 +262,7 @@
          <div className="mk-popover-control">
            <Icon className="plus" title="添加卡片" onClick={this.addCard} type="plus" />
            <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
            <WrapComponent config={card} sysRoles={menu ? menu.sysRoles : []} updateConfig={this.updateComponent} />
            {menu ? <WrapComponent config={card} sysRoles={menu.sysRoles} MenuType={menu.MenuType} updateConfig={this.updateComponent} /> : null}
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="删除组件" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
            {card.wrap.datatype !== 'static' ? <SettingComponent config={card} updateConfig={this.updateComponent} /> : null}
@@ -270,7 +270,7 @@
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} MenuType={menu ? menu.MenuType : ''} cards={card} card={subcard} updateElement={this.updateCard} deleteElement={this.deleteCard}/>))}
      </div>
    )
  }
src/menu/components/chart/antv-bar/index.jsx
@@ -102,7 +102,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu)
  }
  /**
@@ -748,9 +748,9 @@
        </div>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
            <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" />
            <ChartCompileForm config={card} sysRoles={menu ? menu.sysRoles : []} dict={this.state.dict} plotchange={this.updateComponent}/>
            {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> : null}
            {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加按钮" onClick={this.addButton} type="plus-square" /> : null}
            {menu ? <ChartCompileForm config={card} sysRoles={menu.sysRoles} dict={this.state.dict} plotchange={this.updateComponent}/> : null}
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
            <SettingComponent config={card} updateConfig={this.updateComponent}/>
@@ -758,12 +758,12 @@
        } trigger="hover">
          <Icon type="tool" />
        </Popover>
        <ActionComponent
        {menu && menu.MenuType !== 'billPrint' ? <ActionComponent
          type="chart"
          plus="false"
          config={card}
          updateaction={this.updateComponent}
        />
        /> : null}
        <div className="canvas" id={card.uuid}></div>
      </div>
    )
src/menu/components/chart/antv-pie/index.jsx
@@ -91,7 +91,7 @@
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.state), fromJS(nextState)) || (!this.props.menu && nextProps.menu)
  }
  /**
@@ -425,8 +425,8 @@
        </div>
        <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
          <div className="mk-popover-control">
            <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" />
            <ChartCompileForm config={card} sysRoles={menu ? menu.sysRoles : []} dict={this.state.dict} plotchange={this.updateComponent}/>
            {menu && menu.MenuType !== 'billPrint' ? <Icon className="plus" title="添加搜索" onClick={this.addSearch} type="plus-circle" /> : null}
            {menu ? <ChartCompileForm config={card} sysRoles={menu.sysRoles} dict={this.state.dict} plotchange={this.updateComponent}/> : null}
            <Icon className="style" title="调整样式" onClick={this.changeStyle} type="font-colors" />
            <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
            <SettingComponent config={card} updateConfig={this.updateComponent}/>
src/menu/datasource/verifycard/settingform/index.jsx
@@ -206,7 +206,6 @@
      <div className="model-datasource-setting-form-box">
        <Form {...formItemLayout} className="model-setting-form">
          <Row gutter={24}>
            <Col span={8}>
              <Form.Item label="表名">
                {getFieldDecorator('tableName', {
@@ -370,7 +369,7 @@
                </Radio.Group>)}
              </Form.Item>
            </Col> : null}
            <Col span={8}>
            {menu.MenuType !== 'billPrint' ? <Col span={8}>
              <Form.Item label={
                <Tooltip placement="topLeft" title={'该组件如果受其他组件控制,请选项相应的组件,没有时选“无”。'}>
                  <Icon type="question-circle" />
@@ -389,8 +388,8 @@
                  <Cascader options={modules} expandTrigger="hover" placeholder="" />
                )}
              </Form.Item>
            </Col>
            {config.pageable ? <Col span={8}>
            </Col> : null}
            {menu.MenuType !== 'billPrint' && config.pageable ? <Col span={8}>
              <Form.Item label="分页">
                {getFieldDecorator('laypage', {
                  initialValue: setting.laypage || 'true'
@@ -402,7 +401,7 @@
                )}
              </Form.Item>
            </Col> : null}
            {config.pageable && laypage !== 'false' ? <Col span={8}>
            {menu.MenuType !== 'billPrint' && config.pageable && laypage !== 'false' ? <Col span={8}>
              <Form.Item label={
                <Tooltip placement="topLeft" title="选择分页时有效。">
                  <Icon type="question-circle" />
@@ -437,7 +436,7 @@
                )}
              </Form.Item>
            </Col> : null}
            <Col span={8}>
            {menu.MenuType !== 'billPrint' ? <Col span={8}>
              <Form.Item label={
                <Tooltip placement="topLeft" title={'优先使用同级的搜索条件组件,同级搜索不存在时,依次向上选取,与当前组件的搜索条件一同用作数据过滤(当前组件的搜索条件优先)。'}>
                  <Icon type="question-circle" />
@@ -453,8 +452,8 @@
                  </Radio.Group>
                )}
              </Form.Item>
            </Col>
            {useMSearch === 'true' ? <Col span={8}>
            </Col> : null}
            {menu.MenuType !== 'billPrint' && useMSearch === 'true' ? <Col span={8}>
              <Form.Item label={
                <Tooltip placement="topLeft" title={'外层搜索条件改变时,是否刷新当前组件数据。'}>
                  <Icon type="question-circle" />
@@ -471,7 +470,7 @@
                )}
              </Form.Item>
            </Col> : null}
            <Col span={8}>
            {menu.MenuType !== 'billPrint' ? <Col span={8}>
              <Form.Item label="初始化数据">
                {getFieldDecorator('onload', {
                  initialValue: setting.onload || 'true'
@@ -482,7 +481,7 @@
                  </Radio.Group>
                )}
              </Form.Item>
            </Col>
            </Col> : null}
          </Row>
        </Form>
      </div>
src/menu/modelsource/option.jsx
@@ -21,7 +21,7 @@
  { type: 'menu', url: Mainsearch, component: 'search', subtype: 'mainsearch', title: '搜索条件', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: card1, component: 'card', subtype: 'datacard', title: '数据卡', config: `[{"uuid":"160135809128212dm7i29fim9ksto9od","setting":{"width":6},"style":{"paddingTop":"15px","marginTop":"4px","paddingRight":"15px","marginRight":"8px","marginLeft":"8px","backgroundColor":"rgba(255, 255, 255, 1)","borderColor":"#e8e8e8","paddingLeft":"15px","marginBottom":"4px","borderWidth":"1px","paddingBottom":"10px"},"backStyle":{},"elements":[{"datatype":"static","width":12,"marks":null,"height":1,"value":"关单","style":{},"prefix":"","postfix":"","format":"","eleType":"text","uuid":"160231860159931untbea62sgokunc5s"},{"datatype":"dynamic","width":12,"marks":null,"style":{"color":"rgba(250, 219, 20, 1)","textAlign":"right"},"btnstyle":{},"eleType":"icon","icon":"question-circle","field":"nvarchar2","uuid":"1602318768361nv8ql4t47sgcsn88b0u"},{"datatype":"static","width":24,"marks":null,"height":1,"innerHeight":36,"value":"100","style":{"fontSize":"24px","fontWeight":"500","color":"rgba(0, 0, 0, 1)"},"prefix":"","btnstyle":{},"postfix":"","format":"","eleType":"text","uuid":"1602318817884v70gtgb65ubnm8mbcvv"},{"color":"#1890ff","width":24,"marks":null,"maxValue":100,"style":{"color":"rgba(250, 140, 22, 1)","paddingTop":"20px","paddingBottom":"10px"},"btnstyle":{},"eleType":"slider","field":"int1","uuid":"16023188871233rkktuvpp1h077igrsu"},{"eleType":"splitline","width":24,"color":"#e8e8e8","uuid":"1602320017038n31bk9o831ggug0tu0b","marks":null,"style":{"marginTop":"10px","marginBottom":"10px"},"btnstyle":{}},{"datatype":"static","width":12,"marks":null,"height":1,"value":"100","style":{"marginTop":"6px"},"prefix":"关单","btnstyle":{},"postfix":"","format":"","eleType":"text","uuid":"1602320061243drd7lf3agvn04kgr175"}],"backElements":[]}]` },
  { type: 'menu', url: card2, component: 'card', subtype: 'propcard', title: '属性卡', config: `[{"uuid":"1603681387259qaqf1127f72esmtchge","setting":{"width":6,"type":"simple"},"style":{"paddingTop":"15px","marginTop":"8px","paddingRight":"15px","marginRight":"8px","marginLeft":"8px","borderColor":"#e8e8e8","paddingLeft":"15px","marginBottom":"8px","borderWidth":"1px","paddingBottom":"15px"},"backStyle":{},"elements":[{"datatype":"static","width":12,"marks":null,"height":1,"value":"超时工单","style":{"color":"rgba(67, 67, 67, 0.51)"},"prefix":"","postfix":"","format":"","eleType":"text","uuid":"1603681402945qnkgm7q8cng65evn5ev"},{"eleType":"icon","datatype":"static","width":12,"icon":"question-circle","tooltip":"超时工单","uuid":"1603681473384i2crkbtofg4pu76k06a","marks":null,"style":{"textAlign":"right","color":"rgba(250, 219, 20, 1)"}},{"datatype":"static","width":24,"marks":null,"height":1,"innerHeight":36,"value":"100","style":{"fontSize":"24px","color":"rgba(0, 0, 0, 1)"},"prefix":"","postfix":"","format":"","eleType":"number","uuid":"1603681539870d704ufqf98kc6t7537t"},{"color":"rgba(250, 219, 20, 1)","datatype":"static","width":24,"marks":null,"maxValue":100,"value":50,"style":{"paddingTop":"10px","paddingBottom":"10px"},"eleType":"slider","uuid":"1603683067556mvupau0odvrtv45u7o8"},{"eleType":"splitline","width":24,"color":"#e8e8e8","uuid":"1603683117981t9k55k8an430fuppmci","marks":null,"style":{"paddingTop":"5px","paddingBottom":"5px"}},{"datatype":"static","width":12,"marks":null,"height":1,"value":"100","style":{"color":"rgba(0, 0, 0, 0.65)","marginTop":"10px"},"prefix":"超时工单  ","postfix":"","format":"","eleType":"text","uuid":"1603683136553uvsmkfohkft9idbfkhu"}],"backElements":[]}]` },
  { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '表格', width: 12 },
  { type: 'menu', url: TableCard, component: 'table', subtype: 'tablecard', title: '表格', width: 12, forbid: ['billPrint'] },
  { type: 'menu', url: line, component: 'line', subtype: 'line', title: '折线图' },
  { type: 'menu', url: line1, component: 'line', subtype: 'line1', title: '阶梯折线图' },
  { type: 'menu', url: bar, component: 'bar', subtype: 'bar', title: '柱状图' },
src/tabviews/custom/index.jsx
@@ -509,7 +509,6 @@
    })
  }
  render() {
    const { menuType, MenuNo } = this.props
    const { loadingview, viewlost, config } = this.state
src/views/billprint/index.jsx
@@ -1,36 +1,30 @@
import React, { Component } from 'react'
import { DndProvider } from 'react-dnd'
import { is, fromJS } from 'immutable'
import HTML5Backend from 'react-dnd-html5-backend'
import { ConfigProvider, notification, Collapse, Card, Switch, Button } from 'antd'
import { connect } from 'react-redux'
import { Col, Row, Spin, notification } from 'antd'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/mob.js'
import enUS from '@/locales/en-US/mob.js'
import antdEnUS from 'antd/es/locale/en_US'
import antdZhCN from 'antd/es/locale/zh_CN'
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import options from '@/store/options.js'
import NotFount from '@/components/404'
import asyncComponent from '@/utils/asyncComponent'
import './index.scss'
const { Panel } = Collapse
const _locale = localStorage.getItem('lang') !== 'en-US' ? antdZhCN : antdEnUS
const Header = asyncComponent(() => import('@/menu/header'))
const MenuForm = asyncComponent(() => import('@/menu/menuform'))
const SourceWrap = asyncComponent(() => import('@/menu/modelsource'))
const MenuShell = asyncComponent(() => import('@/menu/menushell'))
const BgController = asyncComponent(() => import('@/menu/bgcontroller'))
const PaddingController = asyncComponent(() => import('@/menu/padcontroller'))
const StyleController = asyncComponent(() => import('@/menu/stylecontroller'))
const ModalController = asyncComponent(() => import('@/menu/modalconfig/controller'))
const TableComponent = asyncComponent(() => import('@/templates/sharecomponent/tablecomponent'))
// 通用组件
const AntvBarAndLine = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-bar-line'))
const AntvPie = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-pie'))
const DataCard = asyncComponent(() => import('@/tabviews/custom/components/card/data-card'))
const PropCard = asyncComponent(() => import('@/tabviews/custom/components/card/prop-card'))
class BillPrint extends Component {
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    BID: '',
    data: '',
    tempId: '',
    config: null,
  }
@@ -40,7 +34,7 @@
      let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
      this.setState({
        BID: param.id,
        BID: param.id || '',
        tempId: param.tempId,
      }, () => {
        this.getMenuParam()
@@ -67,9 +61,8 @@
    }
  }
  getMenuParam = () => {
    const { tempId } = this.state
    const { tempId, BID } = this.state
    let param = {
      func: 's_PrintTemplateMGetData',
@@ -83,14 +76,107 @@
    Api.getLocalConfig(param).then(result => {
      if (result.status) {
        // let config = null
        let config = ''
        // try {
        //   config = JSON.parse(window.decodeURIComponent(window.atob(result.ConfigParam)))
        // } catch (e) {
        //   console.warn('Parse Failure')
        //   config = null
        // }
        try {
          config = JSON.parse(window.decodeURIComponent(window.atob(result.ConfigParam)))
        } catch (e) {
          console.warn('Parse Failure')
          config = ''
        }
        setTimeout(() => { // 延时加载状态
          this.setState({
            loadingview: false
          })
        }, 1500)
        // 页面配置解析错误时提示
        if (!config) {
          this.setState({
            viewlost: true
          })
          return
        }
        // 页面未启用时,显示未启用页面
        if (!config.enabled) {
          this.setState({
            viewlost: true,
            lostmsg: this.state.dict['main.view.unenabled']
          })
          return
        }
        let params = []
        config.components = config.components.map(component => {
          if (['tabs', 'search'].includes(component.type)) return null
          if (component.action) component.action = []
          if (component.search) component.search = []
          if (!component.setting) return component // 不使用系统函数时
          if (!component.format || (component.subtype === 'propcard' && component.wrap.datatype === 'static')) return component // 没有动态数据  数据格式 array 或 object
          if (component.setting.interType !== 'system') { // 不使用系统函数时
            component.setting.sync = 'false'
            return component
          }
          let _customScript = ''
          component.scripts && component.scripts.forEach(script => {
            if (script.status !== 'false') {
              _customScript += `
              ${script.sql}
              `
            }
          })
          delete component.scripts
          component.setting.execute = component.setting.execute !== 'false'  // 默认sql是否执行,转为boolean 统一格式
          component.setting.laypage = false   // 是否分页,转为boolean 统一格式
          component.setting.onload = 'true'   // 默认加载
          if (!component.setting.execute) {
            component.setting.dataresource = ''
          }
          if (/\s/.test(component.setting.dataresource)) {
            component.setting.dataresource = '(' + component.setting.dataresource + ') tb'
          }
          if (this.props.dataManager) { // 数据权限
            component.setting.dataresource = component.setting.dataresource.replace(/\$@/ig, '/*')
            component.setting.dataresource = component.setting.dataresource.replace(/@\$/ig, '*/')
            _customScript = _customScript.replace(/\$@/ig, '/*')
            _customScript = _customScript.replace(/@\$/ig, '*/')
          } else {
            component.setting.dataresource = component.setting.dataresource.replace(/@\$|\$@/ig, '')
            _customScript = _customScript.replace(/@\$|\$@/ig, '')
          }
          component.setting.dataresource = component.setting.dataresource.replace(/@BID@/ig, BID)
          _customScript = _customScript.replace(/@BID@/ig, BID)
          component.setting.customScript = _customScript // 整理后自定义脚本
          // floor    组件的层级
          // dataName 系统生成的数据源名称
          // pageable 是否分页,组件属性,不分页的组件才可以统一查询
          if (component.dataName && component.setting.sync === 'true') {
            let param = this.getDefaultParam(component)
            params.push(param)
          } else {
            component.setting.sync = 'false'
          }
          return component
        })
        this.setState({
          setting: config.setting,
          config
        }, () => {
          this.loadmaindata(params)
        })
      } else {
        notification.warning({
          top: 92,
@@ -99,247 +185,160 @@
        })
      }
    })
    // Api.getSystemConfig(param).then(result => {
    //   if (result.status) {
    //     let config = null
    //     try {
    //       config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
    //     } catch (e) {
    //       console.warn('Parse Failure')
    //       config = null
    //     }
    //     if (!config) {
    //       config = {
    //         version: 1.0,
    //         uuid: MenuId,
    //         MenuID: MenuId,
    //         parentId: ParentId,
    //         Template: 'CustomPage',
    //         MenuType: MenuType,
    //         easyCode: '',
    //         enabled: false,
    //         MenuName: MenuName,
    //         MenuNo: MenuNo,
    //         tables: [],
    //         components: [],
    //         style: {
    //           backgroundColor: '#ffffff', backgroundImage: '',
    //           paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px'
    //         }
    //       }
    //     } else {
    //       config.uuid = MenuId
    //       config.MenuID = MenuId
    //       config.MenuType = config.MenuType || MenuType
    //     }
    //     if (MenuType === 'billPrint') {
    //       config.FstID = 'BillPrintTemp'
    //       config.SndID = 'BillPrintTemp'
    //       config.ParentID = 'BillPrintTemp'
    //     }
    //     this.setState({
    //       oriConfig: config,
    //       config: fromJS(config).toJS(),
    //       openEdition: result.open_edition || '',
    //     })
    //     this.getRoleFields()
    //   } else {
    //     notification.warning({
    //       top: 92,
    //       message: result.message,
    //       duration: 5
    //     })
    //   }
    // })
  }
  getRoleFields = () => {
    Api.getSystemConfig({func: 'sPC_Get_Roles_sModular'}).then(res => {
      if (res.status) {
        let _permFuncField = []
        let _sysRoles = []
        if (res.Roles && res.Roles.length > 0) {
          _sysRoles = res.Roles.map(role => {
            return {
              uuid: Utils.getuuid(),
              value: role.RoleID,
              text: role.RoleName
            }
          })
        }
        if (res.sModular && res.sModular.length > 0) {
          res.sModular.forEach(field => {
            if (field.ModularNo) {
              _permFuncField.push(field.ModularNo)
            }
          })
          _permFuncField = _permFuncField.sort()
        }
        let config = {...this.state.config, sysRoles: _sysRoles, permFuncField: _permFuncField}
        this.setState({config})
      }
    })
  }
  initMenuList = (msg) => {
    let config = {...this.state.config, ...msg}
    this.setState({config})
  }
  onEnabledChange = () => {
    const { config } = this.state
    if (!config.enabled && this.verifyConfig(true)) {
      return
    }
    this.setState({
      config: {...config, enabled: !config.enabled}
    })
  }
  verifyConfig = (show) => {
    const { config } = this.state
    let error = ''
    if (!config.MenuID) {
      notification.warning({
        top: 92,
        message: '请完善菜单基本信息!',
        duration: 5
      })
      return
    } else if (config.MenuType === 'custom' && (!config.MenuName || !config.MenuNo || !config.fstMenuId || !config.parentId)) {
      notification.warning({
        top: 92,
        message: '请完善菜单基本信息!',
        duration: 5
      })
      return
    }
    config.components.forEach(item => {
      if (error) return
      if (item.subtype === 'propcard' && item.wrap.datatype === 'static') return
      if (item.setting) {
        if (item.setting.interType === 'system' && item.setting.execute !== 'false' && !item.setting.dataresource) {
          error = `组件《${item.name}》未设置数据源!`
        } else if (item.setting.interType === 'system' && item.setting.execute === 'false' && item.scripts.length === 0) {
          error = `组件《${item.name}》未设置数据源!`
        } else if (item.setting.interType && !item.setting.primaryKey) {
          error = `组件《${item.name}》未设置主键!`
        }
      }
      if (item.type === 'bar' || item.type === 'line' || item.type === 'pie') {
        if (!item.plot.Xaxis) {
          error = `组件《${item.name}》图表字段尚未设置!`
        }
      }
    })
    if (show && error) {
      notification.warning({
        top: 92,
        message: error,
        duration: 5
      })
    }
    return error
  }
  // 更新配置信息
  updateConfig = (config) => {
    this.setState({
      config: config
    })
  }
  /**
   * @description 更新常用表信息,快捷添加后更新配置信息
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   */
  updatetable = (config, fields) => {
    const { tableFields } = this.state
  getDefaultParam = (component) => {
    const { columns, setting, dataName, format } = component
    let arr_field = columns.map(col => col.field)
    let _dataresource = setting.dataresource
    let _customScript = setting.customScript
    config.tableFields = fields ? fields : tableFields
    if (setting.order && _dataresource) {
      _dataresource = `select top 1000 ${arr_field.join(',')} from (select ${arr_field.join(',')} ,ROW_NUMBER() over(order by ${setting.order}) as rows from ${_dataresource}) tmptable order by tmptable.rows `
    } else if (_dataresource) {
      _dataresource = `select top 1000 ${arr_field.join(',')} from ${_dataresource} `
    }
    this.setState({
      tableFields: fields ? fields : tableFields,
      config
    // 测试系统打印查询语句
    if ((options.sysType === 'local' && !window.GLOB.systemType) || window.debugger === true) {
      _customScript &&  console.log(`${_dataresource ? '' : '/*不执行默认sql*/\n'}${_customScript}`)
      _dataresource &&  console.log(_dataresource)
    }
    return {
      name: dataName,
      columns: columns,
      par_tablename: '',
      type: format === 'array' ? format : '',
      primaryKey: setting.primaryKey || '',
      foreign_key: '',
      sql: _dataresource,
      script: _customScript
    }
  }
  /**
   * @description 主表数据加载
   */
  loadmaindata = (params) => {
    if (!params || params.length === 0) return
    let LText_field = []
    let LText = params.map((item, index) => {
      let _sql = item.sql
      let _script = item.script
      if (index === 0) {
        _script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
          ${_script}
        `
      }
      item.columns.forEach(cell => {
        LText_field.push(`Select '${item.name}' as tablename,'${cell.field}' as fieldname,'${cell.datatype}' as field_type`)
      })
      return `Select '${item.name}' as tablename,'${window.btoa(window.encodeURIComponent(_sql))}' as LText,'${window.btoa(window.encodeURIComponent(_script))}' as Lcustomize,'${item.type}' as table_type,'${item.primaryKey}' as primary_key,'${item.par_tablename}' as par_tablename,'${item.foreign_key}' as foreign_key,'${index}' as Sort`
    })
    let param = {
      func: 'sPC_Get_structured_data',
      LText: LText.join(' union all '),
      LText_field: LText_field.join(' union all ')
    }
    param.LText = Utils.formatOptions(param.LText)
    param.LText_field = Utils.formatOptions(param.LText_field)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    Api.getLocalConfig(param).then(result => {
      if (result.status) {
        delete result.status
        delete result.message
        delete result.ErrMesg
        delete result.ErrCode
        this.setState({
          data: result,
          loading: false
        })
      } else {
        this.setState({
          data: '',
          loading: false
        })
        notification.error({
          top: 92,
          message: result.message,
          duration: 10
        })
      }
    })
  }
  render () {
    const { activeKey, MenuType, dict, MenuId, config, ParentId, MenuName, MenuNo, menuloading } = this.state
  getComponents = () => {
    const { dataManager } = this.props
    const { config, BID, data } = this.state
    if (!config || !config.components) return
    return config.components.map(item => {
      if (!item) return null
      if (item.type === 'bar' || item.type === 'line') {
        return (
          <Col span={item.width} key={item.uuid}>
            <AntvBarAndLine config={item} data={data} BID={BID} mainSearch={[]} menuType="" dataManager={dataManager} />
          </Col>
        )
      } else if (item.type === 'pie') {
        return (
          <Col span={item.width} key={item.uuid}>
            <AntvPie config={item} data={data} BID={BID} mainSearch={[]} menuType="" dataManager={dataManager} />
          </Col>
        )
      } else if (item.type === 'card' && item.subtype === 'datacard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <DataCard config={item} data={data} BID={BID} mainSearch={[]} menuType="" dataManager={dataManager} />
          </Col>
        )
      } else if (item.type === 'card' && item.subtype === 'propcard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <PropCard config={item} data={data} BID={BID} mainSearch={[]} menuType="" dataManager={dataManager} />
          </Col>
        )
      } else {
        return null
      }
    })
  }
  render() {
    const { loadingview, viewlost, config } = this.state
    return (
      <ConfigProvider locale={_locale}>
        <div className="pc-menu-view" id="view">
          <Header view="design" closeView={this.closeView} />
          <DndProvider backend={HTML5Backend}>
            <div className="menu-body">
              <div className="menu-setting">
                <Collapse accordion activeKey={activeKey} bordered={false} onChange={(key) => this.setState({activeKey: key})}>
                  {/* 基本信息 */}
                  <Panel header={dict['mob.basemsg']} key="basedata">
                    {/* 菜单信息 */}
                    {config && MenuType === 'custom' ? <MenuForm
                      dict={dict}
                      config={config}
                      MenuId={MenuId}
                      parentId={ParentId}
                      MenuName={MenuName}
                      MenuNo={MenuNo}
                      initMenuList={this.initMenuList}
                      updateConfig={this.updateConfig}
                    /> : null}
                    {/* 表名添加 */}
                    {config ? <TableComponent config={config} updatetable={this.updatetable}/> : null}
                  </Panel>
                  {/* 组件添加 */}
                  <Panel header={dict['mob.component']} key="component">
                    <SourceWrap MenuType={MenuType} />
                  </Panel>
                  <Panel header={'背景'} key="background">
                    {config ? <BgController config={config} updateConfig={this.updateConfig} /> : null}
                  </Panel>
                  <Panel header={'内边距'} key="padding">
                    {config ? <PaddingController config={config} updateConfig={this.updateConfig} /> : null}
                  </Panel>
                </Collapse>
              </div>
              <div className={'menu-view ' + (menuloading ? 'saving' : '')}>
                <Card title={
                  <div> {config && config.MenuName} </div>
                } bordered={false} extra={
                  <div>
                    {config ? <Switch className="big" checkedChildren={dict['mob.enable']} unCheckedChildren={dict['mob.disable']} checked={config.enabled} onChange={this.onEnabledChange} /> : null}
                    <Button type="primary" onClick={this.submitConfig} loading={menuloading}>{dict['mob.save']}</Button>
                  </div>
                } style={{ width: '100%' }}>
                  {config && config.components ? <MenuShell menu={config} handleList={this.updateConfig} /> : null}
                </Card>
              </div>
            </div>
          </DndProvider>
          <StyleController />
          <ModalController />
        </div>
      </ConfigProvider>
      <div className="custom-page-wrap" id={this.state.ContainerId} style={config ? config.style : null}>
        {loadingview && <Spin size="large" />}
        <Row>{this.getComponents()}</Row>
        {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
      </div>
    )
  }
}
export default BillPrint
const mapStateToProps = (state) => {
  return {
    dataManager: state.dataManager
  }
}
const mapDispatchToProps = () => {
  return {}
}
export default connect(mapStateToProps, mapDispatchToProps)(BillPrint)
src/views/menudesign/index.jsx
@@ -160,7 +160,7 @@
      PageParam: JSON.stringify({Template: 'CustomPage', OpenType: 'newtab'}),
      LongParam: window.btoa(window.encodeURIComponent(JSON.stringify(_config))),
      LText: funcs.join(' union all '),
      LTexttb: '', // 表名
      LTexttb: '' // 表名
    }
    param.LText = Utils.formatOptions(param.LText)
@@ -246,31 +246,6 @@
        })
      })
    })
    // Api.getSystemConfig(param).then(response => {
    //   if (response.status) {
    //     this.setState({
    //       oriConfig: fromJS(config).toJS(),
    //       openEdition: response.open_edition || '',
    //       menuloading: false
    //     })
    //     notification.success({
    //       top: 92,
    //       message: '保存成功',
    //       duration: 2
    //     })
    //   } else {
    //     this.setState({
    //       openEdition: response.open_edition || '',
    //       menuloading: false
    //     })
    //     notification.warning({
    //       top: 92,
    //       message: response.message,
    //       duration: 5
    //     })
    //   }
    // })
  }
  getMenuParam = () => {
@@ -299,7 +274,6 @@
            MenuID: MenuId,
            parentId: ParentId,
            Template: 'CustomPage',
            MenuType: MenuType,
            easyCode: '',
            enabled: false,
            MenuName: MenuName,
@@ -309,7 +283,8 @@
            style: {
              backgroundColor: '#ffffff', backgroundImage: '',
              paddingTop: '16px', paddingBottom: '80px', paddingLeft: '16px', paddingRight: '16px'
            }
            },
            MenuType: MenuType
          }
        } else {
          config.uuid = MenuId