king
2022-10-08 9c6795fd3c44e46cf3955fbfd8f8eeca23acb7a9
src/tabviews/calendar/index.jsx
@@ -1,8 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import { is, fromJS } from 'immutable'
import { notification, Spin, Modal, Button, message, Tree, Typography } from 'antd'
import { notification, Spin, Modal, Button } from 'antd'
import moment from 'moment'
import Api from '@/api'
@@ -10,21 +9,19 @@
import zhCN from '@/locales/zh-CN/main.js'
import enUS from '@/locales/en-US/main.js'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import asyncSpinComponent from '@/utils/asyncSpinComponent'
import { refreshTabView } from '@/store/action'
import MainSearch from '@/tabviews/zshare/topSearch'
import MKEmitter from '@/utils/events.js'
import NotFount from '@/components/404'
import './index.scss'
// 通用组件
const MainSearch = asyncComponent(() => import('@/tabviews/zshare/topSearch'))
const CalendarComponent = asyncSpinComponent(() => import('@/tabviews/zshare/calendar'))
const SubTabTable = asyncSpinComponent(() => import('@/tabviews/subtabtable'))
const PagemsgComponent = asyncComponent(() => import('@/tabviews/zshare/pageMessage'))
const { TreeNode } = Tree
const { Paragraph } = Typography
class NormalTable extends Component {
class MkCalendar extends Component {
  static propTpyes = {
    param: PropTypes.any,        // 其他页面传递的参数
    MenuID: PropTypes.string,    // 菜单Id
@@ -42,22 +39,22 @@
    config: {},           // 页面配置信息,包括按钮、搜索、显示列、标签等
    userConfig: null,     // 用户自定义设置
    searchlist: null,     // 搜索条件
    arr_field: '',        // 使用 sPC_Get_TableData 时的查询字段集
    arr_field: '',        // 查询字段集
    setting: null,        // 页面全局设置:数据源、按钮及显示列固定、主键等
    data: null,           // 列表数据集
    loading: false,       // 列表数据加载中
    search: '',           // 搜索条件数组,使用时需分场景处理
    visible: false,       // 标签页控制
    triggerTime: '',      // 点击时间
    treevisible: false,   // 菜单结构树弹框显示隐藏控制
    calendarYear: moment().format('YYYY') // 日历年份
    calendarYear: moment().format('YYYY'), // 日历年份
    hasReqFields: false
  }
  /**
   * @description 获取页面配置信息
   */
  async loadconfig () {
    const { permAction, param } = this.props
    const { param } = this.props
    let _param = {
      func: 'sPC_Get_LongParam',
@@ -78,7 +75,7 @@
      }
      
      // HS不使用自定义设置
      if (result.LongParamUser && this.props.menuType !== 'HS') {
      if (result.LongParamUser && !window.GLOB.mkHS) {
        try { // 配置信息解析
          userConfig = JSON.parse(window.decodeURIComponent(window.atob(result.LongParamUser)))
          _curUserConfig = userConfig[this.props.MenuID]
@@ -108,10 +105,13 @@
      }
      // 权限过滤
      if (this.props.menuType !== 'HS') {
        if (config.tab && !permAction[config.tab.linkTab]) {
      if (!window.GLOB.mkHS) {
        if (config.tab && !window.GLOB.mkActions[config.tab.linkTab]) {
          config.tab = null
        }
      }
      if (config.tab) {
        config.tab.uuid = Utils.getuuid()
      }
      if (_curUserConfig) {
@@ -119,32 +119,17 @@
        config.easyCode = _curUserConfig.easyCode || config.easyCode || ''
      }
      // 字段权限黑名单、必填、字段透视
      let valid = true
      config.search = Utils.initSearchVal(config.search)
      // 字段透视
      let hasReqFields = false
      config.search = config.search.map(item => {
        item.oriInitval = item.initval
        if (['text', 'select', 'link'].includes(item.type) && param) {
          if (param.searchkey === item.field) {
            item.initval = param.searchval
          } else if (param.BID && item.field.toLowerCase() === 'bid') {
            item.initval = param.BID
          } else if (param.data && param.data[item.field]) {
            item.initval = param.data[item.field]
          }
        if (param && ['text', 'select', 'link'].includes(item.type) && param.$searchkey === item.field) {
          item.initval = param.$searchval
        }
        if (item.required === 'true' && !item.initval) {
          valid = false
        }
        if (!item.blacklist || item.blacklist.length === 0) return item
        let _black = item.blacklist.filter(v => {
          return this.props.permRoles.indexOf(v) !== -1
        })
        if (_black.length > 0) {
          item.Hide = 'true'
        if (item.required) {
          hasReqFields = true
        }
        return item
@@ -170,7 +155,7 @@
          config.setting.dataresource = '(' + config.setting.dataresource + ') tb'
        }
    
        if (this.props.dataManager) { // 数据权限
        if (sessionStorage.getItem('dataM') === 'true') { // 数据权限
          config.setting.dataresource = config.setting.dataresource.replace(/\$@/ig, '/*')
          config.setting.dataresource = config.setting.dataresource.replace(/@\$/ig, '*/')
          _customScript = _customScript.replace(/\$@/ig, '/*')
@@ -180,20 +165,49 @@
          _customScript = _customScript.replace(/@\$|\$@/ig, '')
        }
        let userName = sessionStorage.getItem('User_Name') || ''
        let fullName = sessionStorage.getItem('Full_Name') || ''
        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}'` }
        ]
        regs.forEach(cell => {
          config.setting.dataresource = config.setting.dataresource.replace(cell.reg, cell.value)
          _customScript = _customScript.replace(cell.reg, cell.value)
        })
        if (config.urlFields) {
          let _param = param || {}
          config.urlFields.forEach(field => {
            let reg = new RegExp('@' + field + '@', 'ig')
            let val = `'${_param[field] || ''}'`
            config.setting.dataresource = config.setting.dataresource.replace(reg, val)
            _customScript = _customScript.replace(reg, val)
          })
        }
        config.setting.customScript = _customScript
      }
      this.setState({
        BID: param && param.BID ? param.BID : '',
        hasReqFields,
        BID: param && param.$BID ? param.$BID : '',
        loadingview: false,
        config: config,
        userConfig: userConfig,
        setting: config.setting,
        searchlist: config.search,
        arr_field: config.columns.map(item => item.field).join(','),
        search: Utils.initMainSearch(config.search) // 搜索条件初始化(含有时间格式,需要转化)
        search: Utils.initMainSearch(config.search)
      }, () => {
        if (config.setting.onload !== 'false' && valid) { // 初始化可加载
        if (config.setting.onload !== 'false') {
          this.loadmaindata()
        }
      })
@@ -214,20 +228,15 @@
   * @description 主表数据加载
   */ 
  async loadmaindata () {
    const { setting, search, BID } = this.state
    const { setting, search, BID, hasReqFields } = this.state
    let param = ''
    let requireFields = search.filter(item => item.required && (!item.value || item.value.length === 0))
    if (requireFields.length > 0) {
      let labels = requireFields.map(item => item.label)
      labels = Array.from(new Set(labels))
      notification.warning({
        top: 92,
        message: this.state.dict['form.required.input'] + labels.join('、') + ' !',
        duration: 3
      })
      return
    if (hasReqFields) {
      let requireFields = search.filter(item => item.required && item.value === '')
      if (requireFields.length > 0) {
        return
      }
    }
    this.setState({
@@ -244,7 +253,7 @@
      param.BID = BID
    }
    // 数据管理权限
    if (this.props.dataManager) {
    if (sessionStorage.getItem('dataM') === 'true') {
      param.dataM = 'Y'
    }
@@ -288,9 +297,11 @@
    if (setting.interType === 'inner') {
      param.func = setting.innerFunc
    } else {
      if (this.props.menuType === 'HS') {
      if (window.GLOB.mkHS) {
        if (setting.sysInterface === 'true' && options.cloudServiceApi) {
          param.rduri = options.cloudServiceApi
          param.userid = sessionStorage.getItem('CloudUserID') || ''
          param.LoginUID = sessionStorage.getItem('CloudLoginUID') || ''
        } else if (setting.sysInterface !== 'true') {
          param.rduri = setting.interface
        }
@@ -311,7 +322,7 @@
  }
  /**
   * @description 获取系统存储过程 sPC_Get_TableData 的参数
   * @description 获取系统存储过程的参数
   */
  getDefaultParam = () => {
    const { arr_field, search, setting, config, calendarYear } = this.state
@@ -324,34 +335,58 @@
      obj_name: 'data',
      arr_field: arr_field,
      custom_script: setting.customScript,
      default_sql: setting.execute || 'true'
      default_sql: setting.execute || 'true',
      menuname: this.props.MenuName || ''
    }
    
    let _dataresource = setting.dataresource
    let regoptions = null
    let regoptions = []
    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') || ''
    if (sessionStorage.getItem('isEditState') === 'true') {
      userName = sessionStorage.getItem('CloudUserName') || ''
      fullName = sessionStorage.getItem('CloudFullName') || ''
    }
    if (setting.queryType === 'statistics' || param.custom_script) {
      let allSearch = Utils.getAllSearchOptions(search)
      regoptions = allSearch.map(item => {
        return {
          reg: new RegExp('@' + item.key + '@', 'ig'),
          value: `'${item.value}'`
        }
      })
      regoptions.push({
        reg: new RegExp('@userName@', 'ig'),
        value: userName
      }, {
        reg: new RegExp('@fullName@', 'ig'),
        value: fullName
      })
    }
    if (config.calendar.refresh === 'true' && regoptions) {
    if (config.calendar.refresh === 'true') {
      regoptions.push({
        reg: new RegExp('@calendarDate@', 'ig'),
        value: `${calendarYear}-01-01 00:00:00.000`
        value: `'${calendarYear}-01-01 00:00:00.000'`
      })
      regoptions.push({
        reg: new RegExp('@calendarDate1@', 'ig'),
        value: `${calendarYear}-12-31 23:59:59.999`
        value: `'${calendarYear}-12-31 23:59:59.999'`
      })
    }
    if (setting.queryType === 'statistics' && setting.execute !== 'false') { // 统计数据源,内容替换
    if ((setting.queryType === 'statistics' || config.calendar.refresh === 'true') && setting.execute !== 'false') { // 统计数据源,内容替换
      regoptions.forEach(item => {
        _dataresource = _dataresource.replace(item.reg, item.value)
      })
@@ -368,8 +403,9 @@
      regoptions.forEach(item => {
        param.custom_script = param.custom_script.replace(item.reg, item.value)
      })
      param.custom_script = `declare @ErrorCode nvarchar(50),@retmsg nvarchar(4000) select @ErrorCode='',@retmsg =''
      param.custom_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}'
        ${param.custom_script}
      `
@@ -389,9 +425,9 @@
    }
    // 测试系统打印查询语句
    if ((options.sysType === 'local' && !window.GLOB.systemType) || window.debugger === true) {
      param.custom_script &&  console.log(`${LText ? '' : '/*不执行默认sql*/\n'}${param.custom_script}`)
      LText &&  console.log(LText)
    if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) {
      param.custom_script &&  console.info(`${LText ? '' : '/*不执行默认sql*/\n'}${param.custom_script}`)
      LText &&  console.info(LText)
    }
    
    param.custom_script = Utils.formatOptions(param.custom_script)
@@ -400,7 +436,7 @@
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    param.DateCount = ''
    if (this.props.menuType === 'HS') { // 云端数据验证
    if (window.GLOB.mkHS) { // 云端数据验证
      param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
    }
@@ -441,63 +477,12 @@
    })
  }
  handleviewconfig = (e) => {
    e.stopPropagation()
  reloadMenuView = (menuId) => {
    const { MenuID } = this.props
    const { MenuNo } = this.props
    const { config } = this.state
    if (MenuID !== menuId) return
    if (config && config.funcs && config.funcs.length > 0) {
      this.setState({
        treevisible: true
      })
    } else {
      let oInput = document.createElement('input')
      oInput.value = MenuNo || ''
      document.body.appendChild(oInput)
      oInput.select()
      document.execCommand('Copy')
      document.body.removeChild(oInput)
      message.success(this.state.dict['main.copy.success'])
    }
  }
  getTreeNode = (data) => {
    let _type = {
      view: '页面',
      btn: '按钮',
      tab: '标签'
    }
    return data.map(item => {
      let _title = _type[item.subtype]
      let _others = []
      _others.push(
        (item.menuNo ? item.menuNo + '(菜单参数)' : ''),
        (item.tableName ? item.tableName + '(表名) ' : ''),
        (item.innerFunc ? item.innerFunc + '(内部函数) ' : ''),
        (item.outerFunc ? item.outerFunc + '(外部函数)' : '')
      )
      _others = _others.filter(Boolean)
      _others = _others.join('、')
      if (item.label) {
        _title = _title + '(' + item.label + ')'
      }
      if (_others) {
        _title = _title + ': ' + _others
      }
      if (item.subfuncs && item.subfuncs.length > 0) {
        return (
          <TreeNode title={_title} key={item.uuid} dataRef={item} selectable={false}>
            {this.getTreeNode(item.subfuncs)}
          </TreeNode>
        )
      }
      return <TreeNode key={item.uuid} title={_title} isLeaf selectable={false} />
    })
    this.reloadview()
  }
  UNSAFE_componentWillMount () {
@@ -505,27 +490,14 @@
    this.loadconfig()
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps.refreshTab && nextProps.refreshTab.MenuID === this.props.MenuID) {
      if (nextProps.refreshTab.position === 'grid') {
        this.loadmaindata()
      } else if (nextProps.refreshTab.position === 'view') {
        this.reloadview()
      }
      this.props.refreshTabView('')
    } else if (nextProps.param && !is(fromJS(this.props.param), fromJS(nextProps.param))) {
      let search = this.state.search.map(item => {
        if (item.type === 'text' && item.key === nextProps.param.searchkey) {
          item.value = nextProps.param.searchval
        }
        return item
      })
      this.refreshbysearch(search)
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  componentDidMount () {
    MKEmitter.addListener('openNewTab', this.closeTab)
    MKEmitter.addListener('reloadMenuView', this.reloadMenuView)
    MKEmitter.addListener('refreshPopButton', this.refreshPopButton)
  }
  /**
@@ -535,12 +507,17 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('openNewTab', this.closeTab)
    MKEmitter.removeListener('reloadMenuView', this.reloadMenuView)
    MKEmitter.removeListener('refreshPopButton', this.refreshPopButton)
  }
  changeDate = (value) => {
    this.setState({calendarYear: value}, () => {
      this.loadmaindata()
    })
  refreshPopButton = (tabId) => {
    const { config } = this.props
    if (!config.tab || config.tab.uuid !== tabId) return
    this.loadmaindata()
  }
  triggerDate = (item) => {
@@ -562,48 +539,16 @@
  }
  render() {
    const { BID, searchlist, loadingview, viewlost, config, loading, data, triggerTime } = this.state
    const { BID, setting, searchlist, loadingview, viewlost, config, loading, data, triggerTime } = this.state
    return (
      <div className="calendar-page" id={this.state.ContainerId}>
        {loadingview && <Spin size="large" />}
        {searchlist && searchlist.length > 0 ?
          <MainSearch
            BID={BID}
            dict={this.state.dict}
            searchlist={searchlist}
            menuType={this.props.menuType}
            dataManager={this.props.dataManager}
            refreshdata={this.refreshbysearch}
          /> : null
          <MainSearch BID={BID} searchlist={searchlist} setting={setting} refreshdata={this.refreshbysearch}/> : null
        }
        {config && config.calendar ? <CalendarComponent calendar={config.calendar} loading={loading} data={data} triggerDate={this.triggerDate} changeDate={this.changeDate}/> : null}
        {options.sysType !== 'cloud' ? <Button
          icon="copy"
          shape="circle"
          className="common-table-copy"
          onClick={this.handleviewconfig}
        /> : null}
        <Modal
          className="menu-tree-modal"
          title={'菜单结构树'}
          width={'650px'}
          maskClosable={false}
          visible={this.state.treevisible}
          onCancel={() => this.setState({treevisible: false})}
          footer={[
            <Button key="close" onClick={() => this.setState({treevisible: false})}>{this.state.dict['main.close']}</Button>
          ]}
          destroyOnClose
        >
          <div className="menu-header">
            <span>菜单名称:{this.props.MenuName}</span>
            <span>菜单参数:{<Paragraph copyable>{this.props.MenuNo}</Paragraph>}</span>
          </div>
          {this.state.treevisible ? <Tree defaultExpandAll showLine={true}>
            {this.getTreeNode(config.funcs)}
          </Tree> : null}
        </Modal>
        {!window.GLOB.mkHS && window.GLOB.systemType !== 'production' ? <PagemsgComponent menu={{MenuName: this.props.MenuName, MenuNo: this.props.MenuNo}} config={config} dict={this.state.dict} /> : null}
        <Modal
          title={config.tab ? config.tab.label : ''}
          width={'80vw'}
@@ -616,13 +561,10 @@
          destroyOnClose
        >
          {config.tab ? <SubTabTable
            type="calendar"
            BID={triggerTime}
            Tab={config.tab}
            SupMenuID={this.props.MenuID}
            MenuID={config.tab.linkTab}
            refreshSupView={() => this.loadmaindata()}
            closeModalView={this.closeTab}
            SupMenuID={this.props.MenuID}
          /> : null}
        </Modal>
        {viewlost ? <NotFount msg={this.state.lostmsg} /> : null}
@@ -631,21 +573,4 @@
  }
}
const mapStateToProps = (state) => {
  return {
    menuType: state.editLevel,
    tabviews: state.tabviews,
    refreshTab: state.refreshTab,
    permAction: state.permAction,
    permRoles: state.permRoles,
    dataManager: state.dataManager
  }
}
const mapDispatchToProps = (dispatch) => {
  return {
    refreshTabView: (refreshTab) => dispatch(refreshTabView(refreshTab))
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(NormalTable)
export default MkCalendar