king
2020-05-18 763a67d39dcb0e5ae49816abcdb9cb7cbc2bd9e0
2020-05-18
13个文件已修改
3个文件已删除
5个文件已添加
729 ■■■■■ 已修改文件
src/assets/img/A_aFXQS7yyDyUAAAAAAAAAAABkARQnAQ.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/img/A_qpizTrPVB-IAAAAAAAAAAABkARQnAQ.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/img/card1.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/img/card2.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/img/card3.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/img/微信图片_20200426165043.png 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/index.jsx 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/carddetailform/index.jsx 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/carddetailform/index.scss 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/dragdetail/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/dragdetail/index.scss 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/index.jsx 158 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/cardcomponent/index.scss 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartcomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/chartgroupcomponent/chartform/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/settingcomponent/settingform/index.jsx 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/img/A_aFXQS7yyDyUAAAAAAAAAAABkARQnAQ.png
Binary files differ
src/assets/img/A_qpizTrPVB-IAAAAAAAAAAABkARQnAQ.png
Binary files differ
src/assets/img/card1.jpg
src/assets/img/card2.jpg
src/assets/img/card3.jpg
src/assets/img/΢ÐÅͼƬ_20200426165043.png
Binary files differ
src/tabviews/zshare/actionList/index.jsx
@@ -2341,7 +2341,10 @@
    let param = {
      func: 'sPC_Get_TableData',
      obj_name: 'data',
      arr_field: arr_field
      arr_field: arr_field,
      custom_script: setting.customScript || '',
      default_sql: setting.default || 'true',
      dataM: this.props.dataManager ? 'Y' : ''
    }
    if (this.props.BID) {
@@ -2354,37 +2357,58 @@
      _dataresource = '(' + _dataresource + ') tb'
    }
    if (setting.queryType === 'statistics') { // ç»Ÿè®¡æ•°æ®æºï¼Œå†…容替换
      let fieldmap = new Map()
      let options = search.map(item => {
        let _field = item.key
        if (fieldmap.has(_field)) {
          _field = _field + '1'
    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, '')
        }
        fieldmap.set(item.key, true)
    let regoptions = null
    if (setting.queryType === 'statistics' || param.custom_script) {
      let allSearch = Utils.getAllSearchOptions(search)
      regoptions = allSearch.map(item => {
        return {
          reg: new RegExp('@' + _field, 'ig'),
          value: item.value
          reg: new RegExp('@' + item.key + '@', 'ig'),
          value: `'${item.value}'`
        }
      })
      options.reverse()
      options.forEach(item => {
        _dataresource = _dataresource.replace(item.reg, `'${item.value}'`)
      regoptions.push({
        reg: new RegExp('@orderBy@', 'ig'),
        value: orderBy
      }, {
        reg: new RegExp('@pageSize@', 'ig'),
        value: pageSize
      }, {
        reg: new RegExp('@pageIndex@', 'ig'),
        value: pageIndex
      })
    }
    if (setting.queryType === 'statistics') { // ç»Ÿè®¡æ•°æ®æºï¼Œå†…容替换
      regoptions.forEach(item => {
        _dataresource = _dataresource.replace(item.reg, item.value)
      })
      _search = ''
    }
    let LText = ''
    let LText = `select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows`
    if (pagination) {
      LText = `select top ${pageSize} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${_dataresource} ${_search}) tmptable where rows > ${pageSize * (pageIndex - 1)} order by tmptable.rows`
    } else {
      LText = `select ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${orderBy}) as rows from ${_dataresource} ${_search}) tmptable order by tmptable.rows`
    }
    if (param.custom_script) {
      regoptions.forEach(item => {
        param.custom_script = param.custom_script.replace(item.reg, item.value)
      })
      param.custom_script = Utils.formatOptions(param.custom_script)
    }
    param.LText = Utils.formatOptions(LText)
src/templates/comtableconfig/index.jsx
@@ -1099,12 +1099,21 @@
      })
    }
    let charterr = ''
    config.charts.forEach(chart => {
      if (!charterr && ['line', 'bar', 'pie'].includes(chart.chartType) && !chart.Xaxis) {
        charterr = '图表' + (chart.title ? '《' + chart.title + '》' : '') + '坐标轴未设置,不可启用!'
      }
    })
    if (config.setting.interType === 'inner' && !config.setting.innerFunc && !config.setting.dataresource) {
      return '菜单尚未设置数据源,不可启用!'
    } else if (!config.setting.primaryKey) {
      return '菜单尚未设置主键,不可启用!'
    } else if (!tabinvalid) {
      return '菜单标签页设置错误(存在多行标签时,行标签不可为空)!'
    } else if (charterr) {
      return charterr
    } else {
      return true
    }
src/templates/comtableconfig/index.scss
@@ -174,6 +174,7 @@
        margin-bottom: 70px;
        .chart-title {
          min-height: 40px;
          position: relative;
          color: rgba(0, 0, 0, 0.65);
          font-weight: 400;
src/templates/sharecomponent/cardcomponent/carddetailform/index.jsx
New file
@@ -0,0 +1,246 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Icon } from 'antd'
import { formRule } from '@/utils/option.js'
import './index.scss'
class MainSearch extends Component {
  static propTpyes = {
    dict: PropTypes.object,     // å­—典项
    formlist: PropTypes.any,
    card: PropTypes.any,
    inputSubmit: PropTypes.any  // å›žè½¦æäº¤äº‹ä»¶
  }
  state = {
    formlist: null,
    columns: null
  }
  UNSAFE_componentWillMount () {
    const { card } = this.props
    let columns = this.props.formlist.filter(item => item.key === 'field')[0].options
    this.setState({
      columns: columns,
      formlist: this.props.formlist.map(item => {
        if (item.key === 'content' && card.datatype === 'dynamic') {
          item.hidden = true
        } else if (item.key === 'field' && card.datatype === 'static') {
          item.hidden = true
        }
        return item
      })
    })
  }
  componentDidMount () {
  }
  typeChange = (key, value) => {
    if (key === 'datatype') {
      this.setState({
        formlist: this.props.formlist.map(item => {
          item.hidden = false
          if (item.key === 'content' && value === 'dynamic') {
            item.hidden = true
          } else if (item.key === 'field' && value === 'static') {
            item.hidden = true
          }
          return item
        })
      })
      // if (this.props.form.getFieldValue('fieldlength') !== undefined) {
      //   this.props.form.setFieldsValue({fieldlength: fieldlength})
      // }
    }
  }
  handleSubmit = (e) => {
    e.preventDefault()
    if (this.props.inputSubmit) {
      this.props.inputSubmit()
    }
  }
  getFields() {
    const { getFieldDecorator } = this.props.form
    const fields = []
    this.state.formlist.forEach((item, index) => {
      if (item.hidden) return
      if (item.type === 'text') { // æ–‡æœ¬æœç´¢
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} 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 + '!'
                  },
                  {
                    max: formRule.input.max,
                    message: formRule.input.message
                  }
                ]
              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'number') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.tooltip ?
              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} 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 + '!'
                  }
                ]
              })(item.unlimit ? <InputNumber /> :
                  <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.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || '',
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Select
                  showSearch
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  onChange={(value) => {this.typeChange(item.key, value)}}
                  getPopupContainer={() => document.getElementById('card-detail-edit-form')}
                >
                  {item.options.map((option, index) =>
                    <Select.Option id={index} title={option.text} key={index} value={option.value}>
                      {option.text}
                    </Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'radio') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [
                  {
                    required: !!item.required,
                    message: this.props.dict['form.required.select'] + item.label + '!'
                  }
                ]
              })(
                <Radio.Group onChange={(e) => {this.typeChange(item.key, e.target.value)}}>
                  {
                    item.options.map(option => {
                      return (
                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
                      )
                    })
                  }
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'multiselect') { // å¤šé€‰
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={item.label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal || []
              })(
                <Select
                  showSearch
                  mode="multiple"
                  filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                >
                  {item.options.map((option, i) =>
                    <Select.Option id={i} key={i} value={option.value}>{option.text}</Select.Option>
                  )}
                </Select>
              )}
            </Form.Item>
          </Col>
        )
      }
    })
    return fields
  }
  handleConfirm = () => {
    const { columns } = this.state
    // è¡¨å•提交时检查输入值是否正确
    return new Promise((resolve, reject) => {
      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          values.uuid = this.props.card.uuid || ''
          if (values.field && !values.content) {
            values.content = columns.filter(col => col.value === values.field)[0].text
          }
          resolve(values)
        } else {
          reject(err)
        }
      })
    })
  }
  render() {
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 7 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 17 }
      }
    }
    return (
      <Form {...formItemLayout} className="card-detail-edit-form" id="card-detail-edit-form">
        <Row gutter={24}>{this.getFields()}</Row>
      </Form>
    )
  }
}
export default Form.create()(MainSearch)
src/templates/sharecomponent/cardcomponent/carddetailform/index.scss
New file
@@ -0,0 +1,16 @@
.card-detail-edit-form {
  min-height: 190px;
  .ant-form-item {
    .ant-input-number {
      width: 100%;
    }
  }
  .anticon-question-circle {
    color: #c49f47;
    position: relative;
    left: -3px;
  }
  .ant-radio-group {
    white-space: nowrap;
  }
}
src/templates/sharecomponent/cardcomponent/dragdetail/card.jsx
@@ -28,15 +28,22 @@
  })
  let _class = ''
  if (card.type === 'title') {
  if (card.bold === 'true') {
    _class = 'ant-card-meta-title'
  } else {
    _class = 'ant-card-meta-description'
  }
  if (card.width) {
    _class += ' ' + card.width
  }
  if (card.align) {
    _class += ' ' + card.align
  }
  return (
    <div ref={node => drag(drop(node))} className={_class} style={{ opacity: opacity}}>
      <div className="content">{card.content}</div>
      <div className="content" title={card.content}>{card.content}</div>
      <Icon className="edit" title="编辑" type="edit" onClick={() => editCard(card)} />
      <Icon className="edit close" title="删除" type="close" onClick={() => delCard(card)} />
    </div>
src/templates/sharecomponent/cardcomponent/dragdetail/index.jsx
@@ -31,7 +31,7 @@
  })
  return (
    <div ref={drop} className="ant-card-meta-detail">
    <div ref={drop} className="ant-card-meta-detail" style={{marginLeft: 48}}>
      {cards.map(card => (
        <Card
          key={card.uuid}
src/templates/sharecomponent/cardcomponent/dragdetail/index.scss
@@ -1,29 +1,48 @@
.ant-card-meta-detail {
.line-card-edit-box .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;
    font-size: 14px;
    .content {
      max-width: 100%;
      display: inline-block;
      overflow: hidden;
      word-break: break-word;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
  }
  .helf {
    width: 50%;
  }
  .third {
    width: 33.3%;
  }
  .align-center {
    text-align: center;
  }
  .align-right {
    text-align: right;
  }
  .ant-card-meta-title:not(:last-child), .ant-card-meta-description:not(:last-child) {
    margin-bottom: 0px;
  }
  .edit {
    position: absolute;
    left: 0;
    top: -10px;
    font-size: 14px;
    font-size: 13px;
    color: #1890ff;
    cursor: pointer;
    display: none;
    padding: 0 5px;
  }
  .edit.close {
    left: 20px;
src/templates/sharecomponent/cardcomponent/index.jsx
@@ -1,17 +1,18 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Card, Icon } from 'antd'
import { Icon, Modal } 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 { getCardDetailForm } from '@/templates/zshare/formconfig'
import DragDetail from './dragdetail'
import CardDetailForm from './carddetailform'
import './index.scss'
// const { Meta } = Card
const { confirm } = Modal
class LineChart extends Component {
  static propTpyes = {
@@ -22,7 +23,8 @@
  state = {
    dict: (!localStorage.getItem('lang') || localStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS,
    visible: true,
    visible: false,
    formlist: null,
    cardcell: null   // å¡ç‰‡å…ƒç´ 
  }
@@ -57,32 +59,113 @@
  }
  editdetail = (_cell) => {
    const { config } = this.props
    if (!_cell) {
      _cell = {uuid: Utils.getuuid()}
      _cell = {
        datatype: 'dynamic'
      }
    }
    let _columns = config.columns.filter(col => ['text', 'number'].includes(col.type))
    _columns = _columns.map(col => {
      return {
        uuid: col.uuid,
        value: col.field,
        text: col.label
      }
    })
    if (_columns.filter(col => col.value === _cell.field).length === 0) {
      _cell.field = ''
    }
    this.setState({
      cardcell: _cell
      cardcell: _cell,
      visible: true,
      formlist: getCardDetailForm(_cell, _columns)
    })
  }
  deletedetail = () => {
  handleSubmit = () => {
    const { card } = this.props
    let _details = fromJS(card.details).toJS()
    this.detailFormRef.handleConfirm().then(res => {
      if (!res.uuid) {
        res.uuid = Utils.getuuid()
        _details.push(res)
      } else {
        _details = _details.map(item => {
          if (item.uuid === res.uuid) return res
          return item
        })
      }
      this.setState({
        cardcell: null,
        visible: false,
        formlist: null
      })
      this.plotChange({details: _details})
    })
  }
  editModalCancel = () => {
    this.setState({
      cardcell: null,
      visible: false,
      formlist: null
    })
  }
  deletedetail = (cell) => {
    const { card } = this.props
    const { dict } = this.state
    let _this = this
    confirm({
      content: dict['model.confirm'] + dict['model.delete'] + ` - ${cell.content} ï¼Ÿ`,
      okText: dict['model.confirm'],
      cancelText: dict['header.cancel'],
      onOk() {
        let _details = fromJS(card.details).toJS()
        _details = _details.filter(item => item.uuid !== cell.uuid)
        _this.plotChange({details: _details})
      },
      onCancel() {}
    })
  }
  render() {
    const { card } = this.props
    const { dict, visible, cardcell } = this.state
    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 : ''}
        <div
          className={'ant-card ant-card-bordered chart-card' + (card.widthType === 'ratio' ? ' ant-col ant-col-' + card.cardWidth : '')}
          style={card.widthType === 'absolute' ? { width: card.cardWidth } : null}
        >
          <div className="ant-card-head">
            <div className="ant-card-head-wrapper">
              <div className="ant-card-head-title">Card Title</div>
              <div className="ant-card-extra">
                <span>Action</span>
              </div>
            </div>
          </div>
          <div className="ant-card-body">
          <div className="ant-card-meta">
            <Icon type="plus" onClick={this.editdetail} />
              <Icon type="plus" onClick={() => this.editdetail()} />
              {card.cardType === 'card2' ? <div className="ant-card-meta-avatar">
                <span className="ant-avatar ant-avatar-circle ant-avatar-image" style={{width: 32, height: 32}}>
                  <img src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" alt=""/>
                </span>
              </div> : null }
            <DragDetail
              list={card.details}
              handleList={this.handleList}
@@ -90,26 +173,43 @@
              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}
          </div>
          {card.cardType === 'card2' ? <ul className="ant-card-actions">
            <li style={{width: '33.3333%'}}>
              <span>
                <Icon type="setting"/>
              </span>
            </li>
            <li style={{width: '33.3333%'}}>
              <span>
                <Icon type="edit"/>
              </span>
            </li>
            <li style={{width: '33.3333%'}}>
              <span>
                <Icon type="edit"/>
              </span>
            </li>
          </ul> : null}
        </div>
        {/* æ˜¾ç¤ºåˆ—编辑 */}
        <Modal
          title="编辑"
          visible={visible}
          width={650}
          maskClosable={false}
          onOk={this.handleSubmit}
          onCancel={this.editModalCancel}
          destroyOnClose
        >
          <Meta
            avatar={
              <Avatar size={64} src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
            }
            title="Card title"
            description="This is the description"
          <CardDetailForm
            dict={dict}
            card={cardcell}
            inputSubmit={this.handleSubmit}
            formlist={this.state.formlist}
            wrappedComponentRef={(inst) => this.detailFormRef = inst}
          />
        </Card> */}
        {/* <ChartCompileForm
          plot={plot}
          type={plot.chartType}
          config={this.props.config}
          dict={this.state.dict}
          plotchange={this.plotChange}
        /> */}
        </Modal>
      </div>
    )
  }
src/templates/sharecomponent/cardcomponent/index.scss
@@ -2,17 +2,68 @@
  margin-bottom: 30px;
  padding: 30px 20px;
  
  .ant-card {
  .ant-card.chart-card {
    min-height: 100px;
    .ant-card-head {
      min-height: 40px;
      line-height: 2;
      .ant-card-head-title {
        color: #000000;
        font-weight: 500;
      }
      .ant-card-extra {
        cursor: pointer;
        color: #1890ff;
      }
    }
  }
  .ant-card.ant-card-bordered .ant-card-body {
    padding: 20px;
    zoom: 1;
    // .ant-card-meta-avatar {
    .ant-card-meta {
      position: relative;
      >.anticon-plus {
        color: #26C281;
        position: absolute;
        right: -15px;
        top: -5px;
        padding: 5px;
      }
      .ant-card-meta-avatar {
        position: absolute;
        top: 0px;
        left: 0px;
      }
      // .ant-card-meta-avatar + .ant-card-meta-detail {
      //   float: left;
    // }
      .ant-avatar-image {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
        font-variant: tabular-nums;
        line-height: 1.5;
        list-style: none;
        font-feature-settings: 'tnum';
        position: relative;
        display: inline-block;
        overflow: hidden;
        color: #fff;
        white-space: nowrap;
        text-align: center;
        vertical-align: middle;
        border-radius: 50%;
        img {
          width: 100%;
          height: 100%;
        }
      }
    }
  }
  .chart-title {
src/templates/sharecomponent/chartcomponent/index.jsx
@@ -442,7 +442,7 @@
    return (
      <div className="line-chart-edit-box" style={{minHeight: plot.height ? plot.height + 50 : 450}}>
        {plot.title ? <p className="chart-title">{plot.title}</p> : null}
        <p className="chart-title">{plot.title}</p>
        <div className="canvas" id={plot.uuid}></div>
        <ChartCompileForm
          plot={plot}
src/templates/sharecomponent/chartgroupcomponent/chartform/index.jsx
@@ -13,6 +13,9 @@
import bar4 from '@/assets/img/bar4.png'
import pie1 from '@/assets/img/pie1.png'
import pie2 from '@/assets/img/pie2.png'
import card1 from '@/assets/img/card1.jpg'
import card2 from '@/assets/img/card2.jpg'
import card3 from '@/assets/img/card3.jpg'
import './index.scss'
const syslegends = {
@@ -107,13 +110,18 @@
  card: [
    {
      uuid: 'card1',
      url: pie1,
      url: card1,
      type: 'card1'
    },
    {
      uuid: 'card2',
      url: pie2,
      url: card2,
      type: 'card2'
    },
    {
      uuid: 'card3',
      url: card3,
      type: 'card3'
    }
  ]
}
@@ -413,9 +421,11 @@
            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'}
                {bold: 'true', uuid: 'cardtitle', content: 'Card title', datatype: 'static', align: 'left'},
                {bold: 'false', uuid: 'carddescription', content: 'Card content', datatype: 'static', align: 'left'}
              ]
              result.actions = []
              result.title = ''
            }
          }
src/templates/sharecomponent/settingcomponent/settingform/index.jsx
@@ -316,23 +316,26 @@
      let _dataresource = _setting.dataresource
      let _customScript = _setting.customScript
      // æœç´¢æ¡ä»¶
      let allSearch = Utils.initMainSearch(config.search)
      allSearch = Utils.getAllSearchOptions(allSearch)
      // æ˜¾ç¤ºåˆ—字段,用于查询
      let arr_field = []
      config.columns.forEach(col => {
        if (col.field) {
          arr_field.push(col.field)
        }
      })
      arr_field = arr_field.join(',')
      // æ­£åˆ™æ›¿æ¢
      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
@@ -346,6 +349,21 @@
            value: 1
          })
        }
      // æ•°æ®æºå¤„理
      if (/\s/.test(_dataresource)) {
        _dataresource = '(' + _dataresource + ') tb'
      }
      _dataresource = `select ${_setting.laypage !== 'false' ?  'top 10' : ''} ${arr_field} from (select ${arr_field} ,ROW_NUMBER() over(order by ${_setting.order}) as rows from ${_dataresource}) tmptable ${_setting.laypage !== 'false' ?  'where rows > 0' : ''} order by tmptable.rows`
      if (_setting.queryType === 'statistics') {
        regoptions.forEach(item => {
          _dataresource = _dataresource.replace(item.reg, item.value)
        })
      }
      if (_customScript) {
        regoptions.forEach(item => {
          _customScript = _customScript.replace(item.reg, item.value)
        })
src/templates/zshare/formconfig.jsx
@@ -2079,3 +2079,89 @@
    }
  ]
}
/**
 * @description èŽ·å–å¡ç‰‡è¯¦æƒ…è¡¨å•é…ç½®ä¿¡æ¯
 * @param {object} card  // æ ‡ç­¾é…ç½®ä¿¡æ¯
 */
export function getCardDetailForm (card, _columns) {
  return [
    {
      type: 'radio',
      key: 'datatype',
      label: '数据类型',
      initVal: card.datatype || 'dynamic',
      required: true,
      options: [{
        value: 'dynamic',
        text: '动态'
      }, {
        value: 'static',
        text: '静态'
      }]
    },
    {
      type: 'text',
      key: 'content',
      label: '内容',
      initVal: card.content || '',
      required: true
    },
    {
      type: 'select',
      key: 'field',
      label: '字段',
      initVal: card.field || '',
      required: true,
      options: _columns
    },
    {
      type: 'radio',
      key: 'bold',
      label: '加粗',
      initVal: card.bold || 'false',
      required: true,
      options: [{
        value: 'true',
        text: '是'
      }, {
        value: 'false',
        text: '否'
      }]
    },
    {
      type: 'radio',
      key: 'width',
      label: '宽度',
      initVal: card.width || '',
      required: false,
      options: [{
        value: '',
        text: '100%'
      }, {
        value: 'helf',
        text: '50%'
      }, {
        value: 'third',
        text: '33.3%'
      }]
    },
    {
      type: 'radio',
      key: 'align',
      label: '对齐',
      initVal: card.align || '',
      required: false,
      options: [{
        value: '',
        text: 'å·¦'
      }, {
        value: 'align-center',
        text: '居中'
      }, {
        value: 'align-right',
        text: '右'
      }]
    }
  ]
}
src/utils/utils.js
@@ -1141,11 +1141,11 @@
        /* åŒç±»æ•°æ®éªŒè¯ */
        Set @tbid=''
        Select top 1 @tbid='X' from (select ${item.field}${_primaryKey},1 an n from ${datasource} ) tb  inner join (select ID from  dbo.SplitComma(@ID@)) sp on tb.${primaryKey}=sp.ID group by ${item.field} having sum(n)>1
        Select top 1 @tbid='X' from (select ${item.field}${_primaryKey},1 as n from ${datasource} ) tb  inner join (select ID from  dbo.SplitComma(@ID@)) sp on tb.${primaryKey}=sp.ID group by ${item.field} having sum(n)>1
        
        If @tbid!=''
        Begin
          Set @errorcode='E' ,Set @remsg='${item.fieldlabel} å€¼ä¸å”¯ä¸€'
          Set @ErrorCode='E' Set @retmsg='${item.fieldlabel} å€¼ä¸å”¯ä¸€'
          goto aaa
        end
        `