king
2023-10-25 5fdcdee11c98892955a4ea6e5371256dd5ed7c88
src/views/billprint/index.jsx
@@ -5,9 +5,7 @@
import Api from '@/api'
import Utils from '@/utils/utils.js'
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import options from '@/store/options.js'
import { styles } from '@/store/options.js'
import UtilsDM from '@/utils/utils-datamanage.js'
import NotFount from '@/components/404'
import asyncComponent from '@/utils/asyncComponent'
@@ -21,46 +19,131 @@
const AntvScatter = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-scatter'))
const DataCard = asyncComponent(() => import('@/tabviews/custom/components/card/data-card'))
const PropCard = asyncComponent(() => import('@/tabviews/custom/components/card/prop-card'))
const DoubleDataCard = asyncComponent(() => import('@/tabviews/custom/components/card/double-data-card'))
const TableCard = asyncComponent(() => import('@/tabviews/custom/components/card/table-card'))
const NormalTable = asyncComponent(() => import('@/tabviews/custom/components/table/normal-table'))
const SandBox = asyncComponent(() => import('@/tabviews/custom/components/code/sand-box'))
const TimeLine = asyncComponent(() => import('@/tabviews/custom/components/timeline/normal-timeline'))
const BraftEditor = asyncComponent(() => import('@/tabviews/custom/components/editor/braft-editor'))
const Balcony = asyncComponent(() => import('@/tabviews/custom/components/card/balcony'))
const AntvG6 = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-G6'))
const AntvX6 = asyncComponent(() => import('@/tabviews/custom/components/chart/antv-X6'))
const DebugTable = asyncComponent(() => import('@/tabviews/debugtable'))
class BillPrint extends Component {
  state = {
    dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    loadingview: true,
    printing: false,
    pages: null,
    BID: '',
    data: '',
    tempId: '',
    pageId: '',
    config: null,
    urlParam: null,
    visible: false,
    rePos: false,
    loading: false,
    auto: true
  }
  UNSAFE_componentWillMount() {
    try {
      let param = JSON.parse(window.decodeURIComponent(window.atob(this.props.match.params.param)))
    const { params } = this.props.match
      sessionStorage.setItem('dataM', param.dataM || '')
      sessionStorage.setItem('localDataM', param.dataM || '')
    if (params.menuId) {
      this.setState({
        BID: param.id || '',
        tempId: param.tempId
        BID: params.id || '',
        tempId: params.menuId
      }, () => {
        this.getMenuParam()
        this.getTouristMsg()
      })
    } catch (e) {
      notification.warning({
        top: 92,
        message: '菜单信息解析错误!',
        duration: 5
      })
    } else {
      try {
        let param = JSON.parse(window.decodeURIComponent(window.atob(params.param)))
        sessionStorage.setItem('dataM', param.dataM || '')
        this.setState({
          BID: param.id || '',
          tempId: param.tempId,
          urlParam: param,
          pageId: param.pageId || ''
        }, () => {
          setTimeout(() => {
            this.getMenuParam()
          }, 200)
        })
      } catch (e) {
        notification.warning({
          top: 92,
          message: '菜单信息解析错误!',
          duration: 5
        })
      }
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount() {
    const _this = this
    if (window.GLOB.sysType !== 'cloud') {
      Object.defineProperty(window, 'debugger', {
        configurable: true,
        enumerable: true,
        set(value) {
          if (value + '' === 'false') {
            window.GLOB.debugger = false
          } else {
            window.GLOB.debugger = true
          }
        }
      })
      Object.defineProperty(window, 'debug', {
        configurable: true,
        enumerable: true,
        set(value) {
          if (value + '' === 'false') {
            window.GLOB.debugger = false
            window.GLOB.breakpoint = false
            sessionStorage.removeItem('breakpoint')
          } else {
            window.GLOB.debugger = true
            window.GLOB.breakpoint = value + ''
            sessionStorage.setItem('breakpoint', value)
          }
          _this.debugChange()
        }
      })
    }
    document.onkeydown = (event) => {
      let e = event || window.event
      let keyCode = e.keyCode || e.which || e.charCode
      let preKey = ''
      if (e.ctrlKey) {
        preKey = 'ctrl'
      } else if (e.shiftKey) {
        preKey = 'shift'
      } else if (e.altKey) {
        preKey = 'alt'
      }
      if (!preKey || !keyCode) return
      let _shortcut = `${preKey}+${keyCode}`
      if (window.GLOB.breakpoint && _shortcut === 'ctrl+67') {
        window.GLOB.breakpoint = false
        sessionStorage.removeItem('breakpoint')
        _this.debugChange()
      }
    }
  }
  /**
@@ -72,24 +155,77 @@
    }
  }
  debugChange = () => {
    this.setState({visible: !this.state.visible})
  }
  getTouristMsg = () => {
    Api.getTouristMsg().then(result => {
      if (result.status) {
        sessionStorage.setItem('UserID', result.UserID || '')
        sessionStorage.setItem('LoginUID', result.LoginUID || '')
        sessionStorage.setItem('dataM', 'false')
        this.getMenuParam()
        // 获取系统信息
        let _param = {
          func: 's_Get_style',
          TypeCharOne: 'PC',
          LText: `select '${window.GLOB.appkey}'`,
        }
        _param.userid = result.UserID
        _param.LoginUID = result.LoginUID
        _param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
        _param.secretkey = Utils.encrypt(_param.LText, _param.timestamp)
        Api.getSystemConfig(_param).then(res => {
          if (res.status) {
            window.GLOB.style = res.CSS
            document.title = res.titleName
            if (window.GLOB.style && styles[window.GLOB.style]) {
              document.body.className = styles[window.GLOB.style] + ' ' + (res.split_line_show === 'false' ? 'hidden-split-line' : '')
            }
            if (res.titlelogo) {
              let link = document.querySelector("link[rel*='icon']") || document.createElement('link')
              link.type = 'image/x-icon'
              link.rel = 'shortcut icon'
              link.href = res.titlelogo
              document.getElementsByTagName('head')[0].appendChild(link)
            }
          }
        })
      } else {
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
      }
    })
  }
  getMenuParam = () => {
    const { tempId, BID } = this.state
    const { tempId, BID, urlParam } = this.state
    let _param = {
      func: 'sPC_Get_LongParam',
      MenuID: tempId
    }
    if (window.GLOB.mainSystemApi) { // 从单点登录服务器取打印配置信息
      _param.rduri = window.GLOB.mainSystemApi
    }
    window.GLOB.dataFormat = false // 打印去除水印
    Api.getLocalConfig(_param).then(result => {
    Api.getCacheConfig(_param).then(result => {
      if (result.status) {
        let config = ''
        try {
          config = JSON.parse(window.decodeURIComponent(window.atob(result.LongParam)))
          config = window.decodeURIComponent(window.atob(result.LongParam))
          config = config.replace(/@mywebsite@\//ig, window.GLOB.baseurl)
          config = JSON.parse(config)
        } catch (e) {
          console.warn('Parse Failure')
          config = ''
@@ -109,7 +245,7 @@
          this.setState({
            viewlost: true,
            loadingview: false,
            lostmsg: this.state.dict['main.view.unenabled']
            lostmsg: '抱歉,您访问的页面未启用,请联系管理员。'
          })
          return
        }
@@ -161,17 +297,10 @@
        let userName = sessionStorage.getItem('User_Name') || ''
        let fullName = sessionStorage.getItem('Full_Name') || ''
        let city = sessionStorage.getItem('city') || ''
        if (sessionStorage.getItem('isEditState') === 'true') {
          userName = sessionStorage.getItem('CloudUserName') || ''
          fullName = sessionStorage.getItem('CloudFullName') || ''
        }
        let regs = [
          { reg: /@userName@/ig, value: `'${userName}'` },
          { reg: /@fullName@/ig, value: `'${fullName}'` },
          { reg: /@login_city@/ig, value: `'${city}'` }
          { reg: /@fullName@/ig, value: `'${fullName}'` }
        ]
        
        if (window.GLOB.externalDatabase !== null) {
@@ -181,26 +310,172 @@
          })
        }
        if (config.urlFields) {
          config.urlFields.forEach(field => {
            let val = `'${urlParam ? (urlParam[field] || '') : ''}'`
            regs.push({
              reg: new RegExp('@' + field + '@', 'ig'),
              value: val
            })
          })
        }
        window.GLOB.CacheData.set(tempId, {$BID: BID})
        let initInters = []
        this.formatInterSetting(config.interfaces, regs, initInters, params, BID)
        config.components = config.components.map(component => {
          if (component.action) component.action = []
          if (component.search) component.search = []
          if (component.action) {
            component.action = component.action.filter(cell => {
              cell = this.resetButton(component, cell)
              cell.$toolbtn = true
              return !cell.hidden
            })
          }
          if (component.search) {
            component.search = []
            component.$searches = []
          }
          component.data = [] // 初始化数据为空
          if (component.wrap.datatype === 'static') {
          if (component.subtype === 'tablecard') { // 兼容
            component.type = 'card'
          }
          component.$pageId = tempId
          if (component.setting && component.setting.supModule) {
            let pid = component.setting.supModule.pop()
            if (pid && pid !== 'empty') {
              component.setting.supModule = pid
            } else {
              component.setting.supModule = ''
            }
          }
          if (component.type === 'table') {
            let getColumns = (cols) => {
              return cols.filter(item => {
                if (item.Hide === 'true') return false
                if (item.type === 'number') {
                  if (typeof(item.decimal) === 'number') {
                    item.round = Math.pow(10, item.decimal)
                    if (item.format === 'percent') {
                      item.decimal = item.decimal > 2 ? item.decimal - 2 : 0
                    }
                  }
                } else if (item.type === 'formula') {
                  if (typeof(item.decimal) === 'number') {
                    item.round = Math.pow(10, item.decimal)
                  }
                } else if (item.type === 'colspan') {
                  item.subcols = getColumns(item.subcols)
                  if (item.subcols.length === 0) {
                    return false
                  }
                } else if (item.type === 'custom') {
                  item.elements = item.elements.filter(cell => {
                    if (cell.eleType === 'button') {
                      cell = this.resetButton(component, cell)
                      return !cell.hidden
                    }
                    cell = this.resetElement(cell)
                    return true
                  })
                  if (item.elements.length === 0) {
                    return false
                  }
                } else {
                  item.IsSort = 'false'
                }
                return true
              })
            }
            component.cols = getColumns(component.cols)
            component.statFields = []
          } else if (['card', 'carousel', 'timeline'].includes(component.type)) {
            component.subcards && component.subcards.forEach(card => {
              if (card.style.boxShadow) {
                delete card.style.hShadow
                delete card.style.vShadow
                delete card.style.shadowBlur
                delete card.style.shadowColor
              }
              card.elements = card.elements.filter(cell => {
                if (cell.eleType === 'button') {
                  cell = this.resetButton(component, cell)
                  return !cell.hidden
                }
                cell = this.resetElement(cell)
                return true
              })
              if (!card.backElements || card.backElements.length === 0) return
              card.backElements = card.backElements.filter(cell => {
                if (cell.eleType === 'button') {
                  cell = this.resetButton(component, cell)
                  return !cell.hidden
                }
                cell = this.resetElement(cell)
                return true
              })
            })
          } else if (component.type === 'balcony') {
            component.elements = component.elements.filter(cell => {
              if (cell.eleType === 'button') {
                cell = this.resetButton(component, cell)
                return !cell.hidden
              }
              cell = this.resetElement(cell)
              return true
            })
          }
          if (component.wrap && component.wrap.datatype === 'static') {
            component.format = ''
          } else if (component.wrap && component.wrap.datatype === 'public') {
            component.componentId = component.wrap.publicId
            component.format = ''
          }
    
          if (!component.setting) return component // 不使用系统函数时
          if (!component.format) return component  // 没有动态数据  数据格式 array 或 object
          component.setting.arr_field = component.columns ? component.columns.map(col => col.field).join(',') : ''
          if (component.setting.interType !== 'system') { // 不使用系统函数时
            component.setting.sync = 'false'
            return component
          }
    
          let _customScript = ''
          let _tailScript = ''
          component.scripts && component.scripts.forEach(script => {
            if (script.status !== 'false') {
            if (script.status === 'false') return
            if (script.position !== 'back') {
              _customScript += `
              ${script.sql}
              `
            } else {
              _tailScript += `
              ${script.sql}
              `
            }
@@ -219,31 +494,32 @@
          }
      
          if (sessionStorage.getItem('dataM') === 'true') { // 数据权限
            component.setting.dataresource = component.setting.dataresource.replace(/\$@/ig, '/*')
            component.setting.dataresource = component.setting.dataresource.replace(/@\$/ig, '*/')
            _customScript = _customScript.replace(/\$@/ig, '/*')
            _customScript = _customScript.replace(/@\$/ig, '*/')
            component.setting.dataresource = component.setting.dataresource.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
            _customScript = _customScript.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
            _tailScript = _tailScript.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
          } else {
            component.setting.dataresource = component.setting.dataresource.replace(/@\$|\$@/ig, '')
            _customScript = _customScript.replace(/@\$|\$@/ig, '')
            component.setting.dataresource = component.setting.dataresource.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
            _customScript = _customScript.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
            _tailScript = _tailScript.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
          }
          regs.forEach(cell => {
            component.setting.dataresource = component.setting.dataresource.replace(cell.reg, cell.value)
            _customScript = _customScript.replace(cell.reg, cell.value)
            _tailScript = _tailScript.replace(cell.reg, cell.value)
          })
    
          component.setting.customScript = _customScript // 整理后自定义脚本
          component.setting.tailScript = _tailScript     // 后置自定义脚本
    
          // floor    组件的层级
          // dataName 系统生成的数据源名称
          // pageable 是否分页,组件属性,不分页的组件才可以统一查询
          if (component.dataName && component.setting.sync === 'true') {
          if (component.setting.sync === 'true') {
            component.dataName = 'mk' + component.uuid.slice(-18)
            let param = this.getDefaultParam(component)
            _pars.push(param)
          } else {
            let arr_field = component.columns.map(col => col.field).join(',')
            let param = UtilsDM.getQueryDataParams(component.setting, arr_field, [], component.setting.order || '', 1, 1000, BID, '')
          } else if (component.subtype !== 'dualdatacard') {
            let param = UtilsDM.getQueryDataParams(component.setting, [], component.setting.order || '', 1, 1000, BID)
            
            param.componentId = component.uuid
@@ -261,11 +537,26 @@
          params.unshift(_pars)
        }
        if (config.everyPCount && !config.printPage) { // 兼容
          config.printPage = 'page'
        }
        config.printPage = config.printPage || 'auto'
        if (config.printPage === 'auto') {
          config.everyPCount = 99999
        }
        config.limit = config.everyPCount || 15
        this.setState({
          auto: config.printPage === 'auto',
          config
        }, () => {
          if (params.length === 0) {
          if (params.length === 0 && initInters.length === 0) {
            this.setState({loadingview: false, pages: [config.components]})
          } else if (initInters.length > 0) {
            this.loadinit(initInters, params)
          } else {
            this.loadmaindata(params)
          }
@@ -280,49 +571,179 @@
    })
  }
  resetButton = (item, cell) => {
    cell.logLabel = item.$menuname + '-' + cell.label
    cell.Ot = cell.Ot || 'requiredSgl'
    cell.syncComponentId = ''
    cell.$menuId = item.uuid
    cell.hidden = cell.hidden === 'true'
    if (!['pop', 'prompt', 'exec', 'innerpage', 'form'].includes(cell.OpenType)) {
      cell.hidden = true
    }
    if (cell.controlField) {
      if (/,/ig.test(cell.controlVal)) {
        cell.controlVals = cell.controlVal.split(',')
      } else {
        cell.controlVals = [(cell.controlVal || '')]
      }
    }
    return cell
  }
  resetElement = (cell) => {
    cell.style = cell.style || {}
    if (cell.style.display === 'inline-block') {
      cell.style.verticalAlign = 'top'
    }
    if (['text', 'number', 'formula'].includes(cell.eleType)) {
      cell.innerHeight = cell.innerHeight || 'auto'
      cell.alignItems = cell.height > 1 ? cell.alignItems : ''
      if (cell.eleType === 'number' && typeof(cell.decimal) === 'number') {
        cell.round = Math.pow(10, cell.decimal)
        if (cell.format === 'percent') {
          cell.decimal = cell.decimal > 2 ? cell.decimal - 2 : 0
        }
      } else if (cell.eleType === 'formula' && typeof(cell.decimal) === 'number') {
        cell.round = Math.pow(10, cell.decimal)
      }
    }
    return cell
  }
  formatInterSetting = (inters, regs, initInters, params, BID) => {
    if (!inters) return []
    let delay = 15
    inters.forEach(inter => {
      if (inter.status !== 'true') return
      inter.setting.delay = delay
      delay += 15
      inter.setting.supModule = ''
      inter.setting.arr_field = inter.columns.map(col => col.field).join(',')
      if (inter.setting.interType !== 'system') {
        let param = UtilsDM.getQueryDataParams(inter.setting, [], inter.setting.order || '', 1, 1000, BID)
        param.componentId = inter.uuid
        if (inter.setting.loadlevel === 'init') {
          initInters.push(param)
        } else {
          param.public = true
          params.push(param)
        }
        return
      }
      let _customScript = ''
      let _tailScript = ''
      inter.scripts.forEach(script => {
        if (script.status === 'false') return
        if (script.position !== 'back') {
          _customScript += `
          ${script.sql}
          `
        } else {
          _tailScript += `
          ${script.sql}
          `
        }
      })
      delete inter.scripts
      inter.setting.$name = '公共数据源-' + inter.setting.name
      inter.setting.execute = inter.setting.execute !== 'false'
      inter.setting.laypage = true
      if (!inter.setting.execute) {
        inter.setting.dataresource = ''
      }
      if (/\s/.test(inter.setting.dataresource)) {
        inter.setting.dataresource = '(' + inter.setting.dataresource + ') tb'
      }
      if (sessionStorage.getItem('dataM') === 'true') { // 数据权限
        inter.setting.dataresource = inter.setting.dataresource.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
        _customScript = _customScript.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
        _tailScript = _tailScript.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, '\'Y\'')
      } else {
        inter.setting.dataresource = inter.setting.dataresource.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
        _customScript = _customScript.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
        _tailScript = _tailScript.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, '\'\'')
      }
      regs.forEach(cell => {
        inter.setting.dataresource = inter.setting.dataresource.replace(cell.reg, cell.value)
        _customScript = _customScript.replace(cell.reg, cell.value)
        _tailScript = _tailScript.replace(cell.reg, cell.value)
      })
      inter.setting.customScript = _customScript // 整理后自定义脚本
      inter.setting.tailScript = _tailScript     // 后置自定义脚本
      let param = UtilsDM.getQueryDataParams(inter.setting, [], inter.setting.order || '', 1, 1000, BID)
      param.componentId = inter.uuid
      if (inter.setting.loadlevel === 'init') {
        initInters.push(param)
      } else {
        param.public = true
        params.push(param)
      }
    })
  }
  reload = () => {
    const { tempId } = this.state
    this.setState({
      loadingview: true,
      pages: null,
      data: '',
      config: null
    }, () => {
      this.getMenuParam()
      Api.deleteMenuStorage(tempId)
      setTimeout(() => {
        this.getMenuParam()
      }, 50)
    })
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   * @description 获取系统存储过程参数
   */
  getDefaultParam = (component) => {
    const { columns, setting, dataName, format } = component
    
    let arr_field = columns.map(col => col.field)
    let _dataresource = setting.dataresource
    let _customScript = setting.customScript
    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 `
      _dataresource = `select top 1000 ${setting.arr_field} from (select ${setting.arr_field} ,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} `
    }
    // 测试系统打印查询语句
    if ((options.sysType === 'local' && !window.GLOB.systemType) || window.debugger === true) {
      _customScript &&  console.info(`${_dataresource ? '' : '/*不执行默认sql*/\n'}${_customScript}`)
      _dataresource &&  console.info(_dataresource)
      _dataresource = `select top 1000 ${setting.arr_field} from ${_dataresource} `
    }
    return {
      name: dataName,
      columns: columns,
      par_tablename: '',
      order: setting.order || '',
      type: format === 'array' ? format : '',
      primaryKey: setting.primaryKey || '',
      foreign_key: '',
      sql: _dataresource,
      script: _customScript,
      transaction: setting.transaction === 'true'
    }
  }
@@ -331,18 +752,54 @@
    if (!params || params.length === 0) return ''
    let LText_field = []
    let transaction = false
    let userName = sessionStorage.getItem('User_Name') || ''
    let fullName = sessionStorage.getItem('Full_Name') || ''
    let RoleID = sessionStorage.getItem('role_id') || ''
    let departmentcode = sessionStorage.getItem('departmentcode') || ''
    let organization = sessionStorage.getItem('organization') || ''
    let mk_user_type = sessionStorage.getItem('mk_user_type') || ''
    let nation = sessionStorage.getItem('nation') || ''
    let province = sessionStorage.getItem('province') || ''
    let city = sessionStorage.getItem('city') || ''
    let district = sessionStorage.getItem('district') || ''
    let address = sessionStorage.getItem('address') || ''
    let regoptions = [
      { reg: /@pageSize@/ig, value: 9999 },
      { reg: /@pageIndex@/ig, value: 1},
      { reg: /@ID@/ig, value: `''`},
      { reg: /@BID@/ig, value: `'${BID || ''}'`},
      { reg: /@LoginUID@/ig, value: `'${sessionStorage.getItem('LoginUID') || ''}'`},
      { reg: /@SessionUid@/ig, value: `'${localStorage.getItem('SessionUid') || ''}'`},
      { reg: /@UserID@/ig, value: `'${sessionStorage.getItem('UserID') || ''}'`},
      { reg: /@Appkey@/ig, value: `'${window.GLOB.appkey || ''}'`},
      { reg: /@typename@/ig, value: `'admin'`},
    ]
    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 = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000),@UserName nvarchar(50),@FullName nvarchar(50),@RoleID nvarchar(512),@mk_departmentcode nvarchar(512),@mk_organization nvarchar(512),@mk_user_type nvarchar(20),@mk_nation nvarchar(50),@mk_province nvarchar(50),@mk_city nvarchar(50),@mk_district nvarchar(50),@mk_address nvarchar(100)
          select @ErrorCode='',@retmsg ='',@UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}'
          ${_script}
        `
      }
      if (item.transaction) {
        transaction = true
      _sql = _sql.replace(/@orderBy@/ig, item.order)
      _script = _script.replace(/@orderBy@/ig, item.order)
      regoptions.forEach(cell => {
        _sql = _sql.replace(cell.reg, cell.value)
        _script = _script.replace(cell.reg, cell.value)
      })
      // 测试系统打印查询语句
      if (window.GLOB.debugger === true) {
        _script && console.info(`${_sql ? '' : '/*不执行默认sql*/\n'}${_script}`)
        _sql &&  console.info(_sql)
      }
      item.columns.forEach(cell => {
@@ -355,11 +812,9 @@
      func: 'sPC_Get_structured_data',
      LText: LText.join(' union all '),
      LText_field: LText_field.join(' union all '),
      BID: BID || ''
    }
    if (transaction) {
      param.func = 'sPC_Get_structured_data_try'
      BID: BID || '',
      username: userName,
      fullName: fullName
    }
    param.LText = Utils.formatOptions(param.LText)
@@ -370,17 +825,53 @@
    return param
  }
  loadinit = (initInters, params) => {
    let deffers = initInters.map(item => {
      let componentId = item.componentId
      delete item.componentId
      return new Promise(resolve => {
        Api.genericInterface(item).then(res => {
          if (!res.status) {
            notification.warning({
              top: 92,
              message: res.message,
              duration: 5
            })
            resolve()
          } else {
            let _data = { $$empty: true }
            if (res.data && res.data[0]) {
              _data = res.data[0]
            }
            window.GLOB.CacheData.set(componentId, _data)
          }
          resolve()
        })
      })
    })
    Promise.all(deffers).then(() => {
      if (params.length === 0) {
        this.setState({loadingview: false, pages: [this.state.config.components]})
      } else {
        this.loadmaindata(params)
      }
    })
  }
  /**
   * @description 主表数据加载
   */ 
  loadmaindata = (params) => {
    const { components, everyPCount, firstCount, lastCount } = this.state.config
    const { components, limit } = this.state.config
    let deffers = params.map(item => {
      let componentId = item.componentId
      let ispublic = item.public
      delete item.componentId
      delete item.public
      return new Promise(resolve => {
        Api.getLocalConfig(item).then(res => {
        Api.genericInterface(item).then(res => {
          if (!res.status) {
            notification.warning({
              top: 92,
@@ -390,6 +881,14 @@
            resolve(false)
          } else {
            res.componentId = componentId
            if (ispublic) {
              let _data = { $$empty: true }
              if (res.data && res.data[0]) {
                _data = res.data[0]
              }
              window.GLOB.CacheData.set(componentId, _data)
            }
            resolve(res)
          }
        })
@@ -400,17 +899,30 @@
      let _results = results.filter(Boolean)
      let comps = components.map(item => {
        item.wrap = item.wrap || {}
        item.data = null
        if (!item.format) return item
        if ((item.subtype === 'datacard' && item.wrap.layout !== 'flex') || item.type === 'table') {
          item.$page = true
        }
        _results.forEach(res => {
          if (res.componentId === item.uuid && res.data) {
            item.data = res.data
          if ((res.componentId === item.uuid || res.componentId === item.componentId) && res.data) {
            item.dataArray = fromJS(res.data).toJS()
          } else if (res.componentId === 'union' && res[item.dataName]) {
            item.data = res[item.dataName]
            item.dataArray = fromJS(res[item.dataName]).toJS()
            let data = res[item.dataName]
            if (!Array.isArray(data)) {
              data = [data]
            }
            item.dataArray = fromJS(data).toJS()
          }
        })
        if (item.$page && !item.dataArray) {
          item.$page = false
        }
        return item
      })
@@ -424,116 +936,200 @@
        this.setState({loadingview: false, pages})
      }
      let setData = (item) => {
        if (item.setting && item.setting.sync === 'true' && item.data) {
          item.dataName = Utils.getuuid()
          window.GLOB.SyncData.set(item.dataName, item.data)
        }
      }
      while (!over) {
        let page = []
        let count = 0
        let _pageover = false
        let pagesover = false
        let limit = pageIndex === 1 ? (firstCount || 20) : (everyPCount || 20)
        comps.forEach(comp => {
          let item = fromJS(comp).toJS()
        comps.forEach((_item, index) => {
          let item = fromJS(_item).toJS()
          if (index + 1 >= length && !_pageover) {
            pagesover = true
          if (item.wrap.printType === 'headerOrfooter') { // 页眉页脚
            item.data = item.dataArray || null
            setData(item)
            page.push(item)
            comp.added = true
          }
          if (item.wrap && item.wrap.printType === 'headerOrfooter') { // 页眉页脚
            page.push(item)
          } else if (_pageover) {
            return
          } else if (item.subtype === 'datacard' || item.type === 'table') {
            if (_item.dataArray && _item.dataArray.length > 0) {
              item.data = []
          if (_pageover) return
              while (count < limit && _item.dataArray.length > 0) {
                item.data.push(_item.dataArray.shift())
                count++
              }
          if (item.$page && comp.dataArray.length > 0) {
            item.data = []
            while (count + 1 <= limit && comp.dataArray.length > 0) {
              item.data.push(comp.dataArray.shift())
              count++
            }
            if (count >= limit || comp.dataArray.length > 0) {
              _pageover = true
            }
            if (comp.dataArray.length === 0) {
              comp.added = true
            }
            setData(item)
            page.push(item)
          } else if (!comp.added) {
            if (item.wrap.printHeight) {
              count += item.wrap.printHeight
              if (count >= limit) {
                _pageover = true
                return
              }
              page.push(item)
            }
          } else if (!item.added) {
            _item.added = true
            page.push(item)
          }
          if (index + 1 >= length && !_pageover) {
            pagesover = true
            item.data = item.dataArray || null
            setData(item)
            page.push(item)
            comp.added = true
          }
        })
        if (pagesover && lastCount && count > lastCount) {
          pagesover = false
          page = []
          count = 0
          _pageover = false
          if (pageIndex === 1) {
            limit = (everyPCount - firstCount) + (everyPCount - lastCount)
            if (limit <= 0) {
              limit = firstCount
            }
          } else {
            limit = lastCount
          }
          comps.forEach((_item, index) => {
            let item = fromJS(_item).toJS()
            if (item.wrap && item.wrap.printType === 'headerOrfooter') { // 页眉页脚
              page.push(item)
            } else if (_pageover) {
              return
            } else if (item.subtype === 'datacard' || item.type === 'table') {
              if (_item.dataArray && _item.dataArray.length > 0) {
                item.data = []
                while (count < limit && _item.dataArray.length > 0) {
                  item.data.push(_item.dataArray.shift())
                  count++
                }
                if (count >= limit) {
                  _pageover = true
                }
                page.push(item)
              }
            } else if (!item.added) {
              _item.added = true
              page.push(item)
            }
            if (index + 1 === length && !_pageover) {
              pagesover = true
            }
          })
        }
        pages.push(page)
        pageIndex++
        if (pageIndex >= 200 || pagesover) {
        if (pageIndex >= 2000 || comps.findIndex(comp => !comp.added) === -1) {
          over = true
        }
      }
      this.setState({loadingview: false, pages})
      let total = pages.length
      let date = moment().format('YYYY-MM-DD')
      let datetime = moment().format('YYYY-MM-DD HH:mm:ss')
      let rePos = false
      pages.forEach((page, index) => {
        page.forEach(item => {
          if (item.wrap.printType === 'headerOrfooter') { // 页眉页脚
            if (item.type === 'balcony') {
              if (item.style.position === 'absolute') {
                rePos = true
              }
              item.elements.forEach(cell => {
                if (cell.eleType === 'text' && cell.datatype === 'static') {
                  cell.value = cell.value.replace(/@total@/ig, total).replace(/@pageIndex@/ig, index + 1).replace(/@date@/ig, date).replace(/@datetime@/ig, datetime)
                }
              })
            } else if (item.subtype === 'propcard') {
              item.subcards.forEach(card => {
                card.elements.forEach(cell => {
                  if (cell.eleType === 'text' && cell.datatype === 'static') {
                    cell.value = cell.value.replace(/@total@/ig, total).replace(/@pageIndex@/ig, index + 1).replace(/@date@/ig, date).replace(/@datetime@/ig, datetime)
                  }
                })
              })
            }
          }
        })
      })
      this.setState({loadingview: false, pages, rePos})
    })
  }
  print = () => {
    const { config, printing } = this.state
  canvasToImage(canvas) {
    let image = new Image()
    image.src = canvas.toDataURL('image/jpg')
    image.style = 'width:100%;height:100%;position:absolute;z-index:1;left:0px;top:0px;'
    return image
  }
  chartToImage(canvas) {
    let image = new Image()
    image.src = canvas.toDataURL('image/jpg')
    image.style = `width:100%;height:${canvas.style.height || '100%'};`
    return image
  }
  print = () => {
    const { config, printing, BID, tempId, pageId } = this.state
    if (printing) return
    let jubuData = document.getElementById('bill-print').innerHTML
    this.setState({printing: true})
    if (config.callback === 'true') {
      this.setState({loading: true})
      Api.genericInterface({
        func: 's_print_proc',
        username: sessionStorage.getItem('User_Name') || '',
        fullname: sessionStorage.getItem('Full_Name') || '',
        BID: BID || '',
        print_type: config.callNo || '',
        MenuNo: config.MenuNo || '',
        Menuid: tempId || ''
      }).then(res => {
        if (!res.status) {
          notification.warning({
            top: 92,
            message: res.message || '执行失败!',
            duration: 5
          })
          this.setState({printing: false, loading: false})
          return
        }
        let refresh = !/@no_target_menu@/i.test(res.message)
        this.setState({loading: false})
        if (pageId && refresh) {
          localStorage.setItem('menuUpdate', new Date().getTime() + ',' + pageId + ',menu')
        }
        setTimeout(() => {
          this.execPrint()
        }, 300)
      })
    } else {
      this.execPrint()
    }
  }
  execPrint = () => {
    const { config } = this.state
    let qrcodes = document.getElementsByClassName('qrcode-box')
    for (let i = 0; i < qrcodes.length; i++) {
      let canvas = qrcodes[i].getElementsByTagName('canvas')[0]
      if (canvas) {
        let img = this.canvasToImage(canvas)
        canvas.remove()
        qrcodes[i].append(img)
      }
    }
    let charts = document.getElementsByTagName('canvas')
    if (charts.length) {
      for (let i = 0; i < charts.length; i++) {
        let img = this.chartToImage(charts[i])
        let parentNode = charts[i].parentNode
        parentNode.append(img)
      }
      while (charts[0]) {
        charts[0].remove()
      }
    }
    let jubuData = document.getElementById('bill-print').innerHTML
    
    try {
      let iframe = document.createElement('IFRAME')
@@ -551,7 +1147,7 @@
          doc.write(`<LINK rel="stylesheet" type="text/css" href="${linkList[i].href}">`)
        }
      }
      doc.write(`<style>body{width: ${config.width}px!important;}*{border-style: solid;border-width: 0;}</style>`)
      doc.write(`<style>body{width: ${config.width}px!important;}*{border-style: solid;border-width: 0;}.ant-table-placeholder{display: none;}.ant-empty{display: none;}</style>`)
      for (let i = 0;i < styleList.length;i++) {
        doc.write('<style>' + styleList[i].innerHTML + '</style>')
      }
@@ -581,64 +1177,108 @@
  getComponents = (components) => {
    return components.map(item => {
      let style = null
      if (item.style && item.style.clear === 'left') {
        style = {clear: 'left'}
      } else if (item.style && item.style.clear === 'right') {
        style = {float: 'right'}
      }
      if (item.type === 'bar' || item.type === 'line') {
        return (
          <Col span={item.width} key={item.uuid}>
            <AntvBarAndLine config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <AntvBarAndLine config={item}/>
          </Col>
        )
      } else if (item.type === 'pie') {
        return (
          <Col span={item.width} key={item.uuid}>
            <AntvPie config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <AntvPie config={item} />
          </Col>
        )
      } else if (item.type === 'scatter') {
        return (
          <Col span={item.width} key={item.uuid}>
            <AntvScatter config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <AntvScatter config={item}/>
          </Col>
        )
      } else if (item.type === 'dashboard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <AntvDashboard config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <AntvDashboard config={item}/>
          </Col>
        )
      } else if (item.type === 'card' && item.subtype === 'datacard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <DataCard config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <DataCard config={item} />
          </Col>
        )
      } else if (item.type === 'card' && item.subtype === 'propcard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <PropCard config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <PropCard config={item} />
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'tablecard') {
      } else if (item.type === 'card' && item.subtype === 'dualdatacard') {
        return (
          <Col span={item.width} key={item.uuid}>
            <TableCard config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <DoubleDataCard config={item}/>
          </Col>
        )
      } else if (item.type === 'card' && item.subtype === 'tablecard') {
        return (
          <Col span={item.width} style={style} key={item.uuid}>
            <TableCard config={item}/>
          </Col>
        )
      } else if (item.type === 'table' && item.subtype === 'normaltable') {
        return (
          <Col span={item.width} key={item.uuid}>
            <NormalTable config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <NormalTable config={item}/>
          </Col>
        )
      } else if (item.type === 'code') {
        return (
          <Col span={item.width} key={item.uuid}>
            <SandBox config={item} initdata={item.data} mainSearch={[]} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <SandBox config={item}/>
          </Col>
        )
      } else if (item.type === 'balcony') {
        if (item.wrap.printType === 'headerOrfooter' && item.style.position === 'absolute') {
          return (
            <Balcony key={item.uuid} config={item}/>
          )
        } else {
          return (
            <Col span={item.width} style={style} key={item.uuid}>
              <Balcony config={item}/>
            </Col>
          )
        }
      } else if (item.type === 'timeline') {
        return (
          <Col span={item.width} key={item.uuid}>
            <TimeLine config={item} initdata={item.data} menuType="" />
          <Col span={item.width} style={style} key={item.uuid}>
            <TimeLine config={item}/>
          </Col>
        )
      } else if (item.type === 'editor') {
        return (
          <Col span={item.width} style={style} key={item.uuid}>
            <BraftEditor config={item}/>
          </Col>
        )
      } else if (item.type === 'antvG6') {
        return (
          <Col span={item.width} style={style} key={item.uuid}>
            <AntvG6 config={item}/>
          </Col>
        )
      } else if (item.type === 'antvX6') {
        return (
          <Col span={item.width} style={style} key={item.uuid}>
            <AntvX6 config={item}/>
          </Col>
        )
      } else {
@@ -648,15 +1288,16 @@
  }
  render() {
    const { loadingview, viewlost, config, pages } = this.state
    const { loadingview, viewlost, config, pages, auto, rePos, loading } = this.state
    return (
      <div className="bill-print-wrap" >
        {loadingview && <Spin size="large" />}
        {loadingview || loading ? <Spin size="large" /> : null}
        {pages ? <div id="bill-print">
          {pages.map((components, index) => (<div className="print-page" key={index} style={{...config.style, overflow: 'hidden', boxSizing: 'border-box'}}><Row>{this.getComponents(components)}</Row></div>))}
          {pages.map((components, index) => (<div className={'print-page' + (auto ? ' auto' : '') + (rePos ? ' reset-position' : '')} key={index} style={{...config.style, overflow: 'hidden', boxSizing: 'border-box'}}><Row className="component-wrap">{this.getComponents(components)}</Row></div>))}
        </div> : null}
        {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
        {config && window.GLOB.breakpoint ? <DebugTable /> : null}
        {pages && !loadingview && !viewlost ? <div className="print-button"><Button icon="printer" size="large" shape="circle" onClick={this.print}></Button></div> : null}
        {!loadingview && !viewlost ? <div className="refresh-button"><Button icon="reload" size="large" shape="circle" onClick={this.reload}></Button></div> : null}
      </div>