king
2020-06-28 48a18736c461ad730bd264b0ac7b40b68a0e33a1
2020-06-28
28个文件已修改
680 ■■■■■ 已修改文件
package-lock.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/header/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/sidemenu/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tabview/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/index.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/en-US/model.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/locales/zh-CN/model.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/login/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/options.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/excelInbutton/index.jsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/exceloutbutton/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/fileupload/index.jsx 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/comtableconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/formtabconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/columnform/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/sharecomponent/columncomponent/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/subtableconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/treepageconfig/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils.js 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -15753,6 +15753,11 @@
      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
    },
    "spark-md5": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.1.tgz",
      "integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig=="
    },
    "spdx-correct": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
package.json
@@ -78,6 +78,7 @@
    "resolve-url-loader": "3.1.0",
    "sass-loader": "7.2.0",
    "semver": "6.3.0",
    "spark-md5": "^3.0.1",
    "style-loader": "1.0.0",
    "terser-webpack-plugin": "1.4.1",
    "ts-pnp": "1.1.2",
src/api/index.js
@@ -82,7 +82,7 @@
      // func: 'webapi_login',
      UserName: username,
      Password: password,
      systemType: options.systemType,
      systemType: options.sysType,
      Type: 'X'
    }
@@ -91,8 +91,8 @@
    if (isCloud) {
      param.debug = 'Y'
      if (options.cloudLoginApi) {
        param.rduri = options.cloudLoginApi
      if (options.cloudServiceApi) {
        param.rduri = options.cloudServiceApi.replace(/\/webapi(.*)/, '/webapi/dologon')
      }
    } else if (!isCloud && window.GLOB.mainSystemApi) {
      param.rduri = window.GLOB.mainSystemApi.replace(/\/webapi(.*)/, '/webapi/dologon')
@@ -143,7 +143,7 @@
    param.t = new Date().getTime()
    return axios({
      url: '/webapi/dostars',
      url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
      data: param
    })
  }
@@ -183,7 +183,7 @@
    param.t = new Date().getTime()
    return axios({
      url: '/webapi/dostars',
      url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
      data: param
    })
  }
@@ -214,7 +214,7 @@
    param.t = new Date().getTime()
    return axios({
      url: '/webapi/dostars',
      url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
      data: param
    })
  }
@@ -268,7 +268,7 @@
      return new Promise(resolve => {
        axios({
          url: '/webapi/dostars',
          url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
          data: param
        }).then(res => {
          if (res.status) {
@@ -312,7 +312,7 @@
    param.t = new Date().getTime()
    return axios({
      url: '/webapi/dostars',
      url: `/webapi/dostars${param.func ? '/' + param.func : ''}`,
      data: param
    })
  }
@@ -438,6 +438,16 @@
  }
  /**
   * @description 查询文件是否已上传
   */
  getFilePreUpload (param) {
    return axios({
      url: '/webapi/dopreload',
      data: param
    })
  }
  /**
   * @description 文件上传
   */
  getFileUpload (param) {
src/components/header/index.jsx
@@ -155,11 +155,11 @@
  async loadmenu () {
    // 获取主菜单
    let _param = {func: 'sPC_Get_MainMenu', systemType: options.systemType}
    let _param = {func: 'sPC_Get_MainMenu', systemType: options.sysType}
    if (sessionStorage.getItem('isEditState') === 'true') { // 编辑状态时,获取一级菜单,增加参数debug
      _param.debug = 'Y'
    }
    if (options.systemType !== 'cloud' && window.GLOB.systemType !== 'official') {
    if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'official') {
      _param.linkurl = window.GLOB.linkurl
    }
@@ -244,8 +244,8 @@
    
    // 获取主菜单参数
    let promiseMenu = new Promise(resolve => {
      let _param = {func: 'sPC_Get_MainMenu', systemType: options.systemType}
      if (options.systemType !== 'cloud' && window.GLOB.systemType !== 'official') {
      let _param = {func: 'sPC_Get_MainMenu', systemType: options.sysType}
      if (options.sysType !== 'cloud' && window.GLOB.systemType !== 'official') {
        _param.linkurl = window.GLOB.linkurl
      }
@@ -678,7 +678,7 @@
        {this.props.editLevel === 'HS' ? <Button className="level4-close" type="primary" onClick={this.exitManage}>退出</Button> : null}
        {/* 进入编辑按钮 */}
        {this.props.editState && !this.props.editLevel ? <Icon onClick={this.enterEdit} className="edit-check" type="edit" /> : null}
        {/* {this.props.editState && !this.props.editLevel && options.systemType === 'local' && window.GLOB.systemType !== 'official' ?
        {/* {this.props.editState && !this.props.editLevel && options.sysType === 'local' && window.GLOB.systemType !== 'official' ?
          <a href="#/mobmanage" target="_blank" className="mobile" type="edit"> 应用管理 <Icon type="arrow-right" /></a> : null
        } */}
        {/* 编辑菜单 */}
src/components/sidemenu/index.jsx
@@ -49,7 +49,7 @@
      return
    }
    let _param = {func: 'sPC_Get_FunMenu', ParentID: menu.MenuID, systemType: options.systemType}
    let _param = {func: 'sPC_Get_FunMenu', ParentID: menu.MenuID, systemType: options.sysType}
    if (sessionStorage.getItem('isEditState') === 'true') { // 编辑状态时,获取菜单,增加参数debug
      _param.debug = 'Y'
@@ -182,7 +182,7 @@
      menulist = menulist.filter(menu => menu.children.length > 0)
    } else {
      menulist.forEach(menu => {
        menu.children = menu.children.filter(item => !item.systems || item.systems.includes(options.systemType))
        menu.children = menu.children.filter(item => !item.systems || item.systems.includes(options.sysType))
      })
    }
src/components/tabview/index.jsx
@@ -45,8 +45,8 @@
  state = {
    tabviews: null, // 标签集
    iFrameHeight: 0,
    dict: (!sessionStorage.getItem('lang') || sessionStorage.getItem('lang') === 'zh-CN') ? mzhCN : menUS,
    locale: (!sessionStorage.getItem('lang') || sessionStorage.getItem('lang') === 'zh-CN') ? zhCN : enUS
    dict: localStorage.getItem('lang') !== 'en-US' ? mzhCN : menUS,
    locale: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS
  }
  handleTabview = (e, menu) => {
src/index.js
@@ -14,6 +14,10 @@
  window.location.replace(window.location.href.split(/(index.html)+/ig)[0] + 'mob/index.html')
}
if (options.cdomain) {
  options.cloudServiceApi = options.cdomain + '/webapi/dostars'
}
const render  = Component => {
  ReactDOM.render(
    <Provider store={store}>
@@ -25,32 +29,46 @@
window.GLOB = window.GLOB || {}
if (!(options.systemType === 'local' && window.GLOB.systemType === 'official')) { // 只有业务系统才可以设置为正式系统
if (!(options.sysType === 'local' && window.GLOB.systemType === 'official')) { // 只有业务系统才可以设置为正式系统
  window.GLOB.systemType = ''
}
if (options.systemType !== 'local') { // sso,cloud不可设置单点服务器地址
if (options.sysType === 'cloud') { // cloud不可设置单点服务器地址,云端appkey为系统设置
  window.GLOB.appkey = options.cakey
  window.GLOB.mainSystemApi = ''
} else if (options.systemType === 'local' && window.GLOB.mainSystemApi) { // 业务系统
  let systemApi = window.GLOB.mainSystemApi
  if (/^(http|https):\/\//ig.test(systemApi)) {
    let _systemApi = /^(http|https):\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}|(:[0-9]{1,4}))+\.?/ig.exec(systemApi)
    systemApi = _systemApi ? _systemApi[0] : ''
  } else {
    systemApi = ''
} else if (options.sysType === 'SSO') { // sso不可设置单点服务器地址
  window.GLOB.mainSystemApi = ''
  if (window.GLOB.appkey === options.cakey) {
    window.GLOB.appkey = ''
    console.warn('单点系统appkey不可与云端相同')
  }
  // 业务系统连接云端时,格式化处理
  if (systemApi && systemApi === /^(http|https):\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}|(:[0-9]{1,4}))+\.?/ig.exec(options.cloudServiceApi)[0]) {
    window.GLOB.dataFormat = true
} else if (options.sysType === 'local') { // 业务系统
  if (window.GLOB.appkey === options.cakey) {
    window.GLOB.appkey = ''
    console.warn('业务系统appkey不可与云端相同')
  }
  if (systemApi) {
    systemApi = systemApi + '/webapi/dostars'
  if (window.GLOB.mainSystemApi) {
    let systemApi = window.GLOB.mainSystemApi
    if (/^(http|https):\/\//ig.test(systemApi)) {
      let _systemApi = /^(http|https):\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}|(:[0-9]{1,4}))+\.?/ig.exec(systemApi)
      systemApi = _systemApi ? _systemApi[0] : ''
    } else {
      systemApi = ''
    }
    // 业务系统连接云端时,格式化处理
    if (systemApi && systemApi === /^(http|https):\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}|(:[0-9]{1,4}))+\.?/ig.exec(options.cloudServiceApi)[0]) {
      window.GLOB.dataFormat = true
    }
    if (systemApi) {
      systemApi = systemApi + '/webapi/dostars'
    }
    window.GLOB.mainSystemApi = systemApi
  }
  window.GLOB.mainSystemApi = systemApi
}
let _systemMsg = localStorage.getItem(window.location.href.split('#')[0] + 'system')
src/locales/en-US/model.js
@@ -14,6 +14,8 @@
  'model.enable': 'Enable',
  'model.disable': 'Disable',
  'model.required': 'Required',
  'model.import': 'Import ',
  'model.export': 'Export ',
  'model.hidden': 'Hidden',
  'model.length': 'Length',
  'model.sort': 'Sort',
@@ -41,7 +43,7 @@
  'model.menu.itemsUnit': 'Items',
  'model.menu.close': 'Are you sure to delete the menu <<@M>> ?',
  'model.menu.resetorder': 'Are you sure to adjust the menu sequence ?',
  'header.menu.basemsg': 'Please complete the basic information !',
  'model.menu.basemsg': 'Please complete the basic information !',
  'header.menu.basedata': 'The basic information',
  'header.menu.table.add': 'Add tables',
  'header.menu.table.placeholder': 'Please select a table',
src/locales/zh-CN/model.js
@@ -14,6 +14,8 @@
  'model.enable': '启',
  'model.disable': '停',
  'model.required': '必填',
  'model.import': '导入',
  'model.export': '导出',
  'model.hidden': '隐藏',
  'model.length': '长度',
  'model.sort': '排序',
@@ -41,7 +43,7 @@
  'model.menu.itemsUnit': '项',
  'model.menu.close': '确定删除《@M》菜单吗?',
  'model.menu.resetorder': '确认调整菜单顺序吗?',
  'header.menu.basemsg': '请完善菜单基本信息!',
  'model.menu.basemsg': '请完善菜单基本信息!',
  'header.menu.basedata': '基本信息',
  'header.menu.table.add': '添加表名',
  'header.menu.table.placeholder': '请选择表名',
src/mob/login/index.jsx
@@ -99,7 +99,7 @@
    const { card, editId } = this.props
    const { getFieldProps } = this.props.form
    const { rember } = this.state
    console.log(editId)
    return (
      <div className="mob-login" onClick={this.editBox} style={{paddingTop: `calc(17vh - 10px)`}}>
        <div className={'logo ' + (editId === card.logo.uuid ? 'editing' : '')} onClick={this.editLogo}>
src/store/options.js
@@ -1,7 +1,7 @@
// 系统配置
export default {
  systemType: 'local', // cloud 、 SSO 、 local, 云端使用系统配置appId
  AppId: '',
  cloudServiceApi: 'http://cloud.mk9h.cn/webapi/dostars',
  cloudLoginApi: 'http://cloud.mk9h.cn/webapi/dologon'
  sysType: 'local', // cloud 、 SSO 、 local
  caId: '',
  cakey: '2020011612400464367D38162115B417895C1',
  cdomain: 'http://cloud.mk9h.cn'
}
src/tabviews/zshare/actionList/excelInbutton/index.jsx
@@ -228,6 +228,7 @@
    }
    let result = Utils.getExcelInSql(btn, data, this.state.dict)
    if (result.errors) {
      notification.warning({
        top: 92,
@@ -239,27 +240,32 @@
    }
    let param = {
      ID: this.state.primaryId
      ID: this.state.primaryId,
      excel_in: result.lines
    }
    if (this.props.BID) {
      param.BID = this.props.BID
    }
    if (this.props.dataManager) { // 数据权限
      result.sql = result.sql.replace(/\$@/ig, '/*')
      result.sql = result.sql.replace(/@\$/ig, '*/')
    } else {
      result.sql = result.sql.replace(/@\$|\$@/ig, '')
    }
    param.LText = Utils.formatOptions(result.sql)
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
    param.secretkey = Utils.encrypt(param.LText, param.timestamp)
    if (btn.intertype === 'inner' && !btn.innerFunc) { // 系统存储过程
      param.func = 'sPC_TableData_InUpDe'
      
      if (this.props.dataManager) { // 数据权限
        result.sql = result.sql.replace(/\$@/ig, '/*')
        result.sql = result.sql.replace(/@\$/ig, '*/')
        result.bottom = result.bottom.replace(/\$@/ig, '/*')
        result.bottom = result.bottom.replace(/@\$/ig, '*/')
      } else {
        result.sql = result.sql.replace(/@\$|\$@/ig, '')
        result.bottom = result.bottom.replace(/@\$|\$@/ig, '')
      }
      param.LText_insert = Utils.formatOptions(result.insert)
      param.LText_bottom = Utils.formatOptions(result.bottom)
      param.LText = Utils.formatOptions(result.sql)
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + '.000'
      param.secretkey = Utils.encrypt(param.LText, param.timestamp)
      if (this.props.menuType === 'HS' && param.timestamp) { // 云端验证
        param.open_key = Utils.encrypt(param.secretkey, param.timestamp, true)
      }
src/tabviews/zshare/actionList/exceloutbutton/index.jsx
@@ -376,12 +376,16 @@
        let verifyColumn = {} // 记录验证信息中的Excel列配置
        if (btn.verify && btn.verify.columns && btn.verify.columns.length > 0) {
          btn.verify.columns.forEach(col => {
            if (col.export === 'false') {
              hidecolumns.push(col.Column)
              return
            }
            verifyColumn[col.Column] = col
          })
        }
        columns.forEach(col => {
          if (col.Hide === 'true') {
          if (col.Hide === 'true' || hidecolumns.includes(col.field)) {
            hidecolumns.push(col.field)
            return
          }
src/tabviews/zshare/fileupload/index.jsx
@@ -1,13 +1,21 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Upload, message, Button, Icon, Progress, notification } from 'antd'
import md5 from 'md5'
import { fromJS } from 'immutable'
import { Upload, Button, Icon, Progress, notification } from 'antd'
import SparkMD5 from 'spark-md5'
import Api from '@/api'
import './index.scss'
let Url = '/Upload'
if (process.env.NODE_ENV === 'production') {
  Url = document.location.origin + '/' + window.GLOB.service + 'zh-CN/Home/Upload'
}
let service = ''
if (process.env.NODE_ENV === 'production') {
  service = document.location.origin + '/' + window.GLOB.service
} else {
  service = window.GLOB.location + window.GLOB.service
}
class FileUpload extends Component {
@@ -21,18 +29,6 @@
    baseUrl: Url,
    percent: 0,
    showprogress: false
  }
  init = async () => {
    try {
      const OSSData = await this.mockGetOSSData()
      this.setState({
        OSSData
      })
    } catch (error) {
      message.error(error)
    }
  }
  onChange = ({ fileList }) => {
@@ -53,89 +49,180 @@
    }
  }
  onUpdate = (url) => {
    const { value, onChange } = this.props
    let filelist = fromJS(value).toJS()
    filelist[filelist.length -1].status = 'done'
    filelist[filelist.length -1].response = url
    filelist[filelist.length -1].origin = false
    if (onChange) {
      onChange([...filelist])
    }
  }
  onDelete = (msg) => {
    const { value, onChange } = this.props
    let filelist = value.filter(v => !v.url && !v.response)
    if (onChange) {
      onChange([...filelist])
    }
    this.setState({
      showprogress: false
    })
    notification.warning({
      top: 92,
      message: msg || '文件上传失败!',
      duration: 5
    })
  }
  getExtraData = () => {
    return {
      RootPath: 'Content/images/upload/'
    }
  }
  shardupload = (file, shardSize, shardCount, i, fileList) => {
    let start = i * shardSize
    let end = Math.min(file.size, start + shardSize)
    // let param = {
    //   file: file.slice(start, end),
    //   fileMd5: md5(''),
    //   shardingMd5: md5(''),
    //   baseDomain: '',
    //   rootPath: 'Content/images/upload/',
    //   fileName: file.name,
    //   fileExt: file.type.replace('image/', ''),
    //   shardingCnt: shardCount,
    //   shardingNo: i + 1
    // }
  shardupload = (params) => {
    let param = params.chunks.shift()
    let form = new FormData()
    let pice = file.slice(start, end)
    form.append('file', pice) //slice方法用于切出文件的一部分
    form.append('fileMd5', md5(file))
    form.append('shardingMd5', md5(pice))
    form.append('baseDomain', '')
    form.append('file', param.binary)
    form.append('fileMd5', params.file.fileMd5)
    form.append('shardingMd5', param.chunkMd5)
    form.append('baseDomain', service)
    form.append('rootPath', 'Content/images/upload/')
    form.append('fileName', file.name)
    form.append('fileExt', file.type.replace('image/', ''))
    form.append('shardingCnt', shardCount)
    form.append('shardingNo', i + 1)
    form.append('fileName', params.file.fileName)
    form.append('fileExt', params.file.fileType)
    form.append('shardingCnt', param.chunks)
    form.append('shardingNo', param.chunk)
    Api.getLargeFileUpload(form).then(res => {
      if (res.status) {
        if (i < shardCount) {
          i++
        if (params.chunks.length > 0) {
          this.setState({
            percent: Math.floor(100 * (i / shardCount))
            percent: Math.floor(100 * (param.chunk / param.chunks))
          })
          this.shardupload(file, shardSize, shardCount, i, fileList)
          this.shardupload(params)
        } else {
          if (res.urlPath) {
            this.onUpdate(res.urlPath)
          } else {
            this.onDelete()
          }
          this.setState({
            percent: 100
          }, () => {
            setTimeout(() => {
              this.setState({
                showprogress: false,
                percent: 0
              })
            }, 200)
          })
        }
      } else {
        fileList = fileList.filter(item => !!item.url)
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        this.onDelete(res.message)
      }
    })
    // } else {
    //   this.setState({
    //     percent: 100
    //   }, () => {
    //     setTimeout(() => {
    //       this.setState({
    //         showprogress: false,
    //         percent: 0
    //       })
    //     }, 200)
    //   })
    // }
  }
  beforeUpload = (file, fileList) => {
    let shardSize = 2 * 1024 * 1024
  beforeUpload = (file) => {
    this.setState({
      showprogress: true,
      percent: 0
    })
    if (file.size > shardSize) {
      // this.setState({
      //   showprogress: true,
      //   percent: 0
      // })
      // let shardCount = Math.ceil(file.size / shardSize)
    // 兼容性的处理
    let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
    let chunkSize = 1024 * 1024 * 2                // 切片每次2M
    let chunks = Math.ceil(file.size / chunkSize)  // 切片总数
    let currentChunk = 0                           // 当前上传的chunk
    let spark = new SparkMD5.ArrayBuffer()         // 对arrayBuffer数据进行md5加密,产生一个md5字符串
    let chunkFileReader = new FileReader()         // 用于计算出每个chunkMd5
    let totalFileReader = new FileReader()         // 用于计算出总文件的fileMd5
    let params = {chunks: [], file: {}}            // 用于上传所有分片的md5信息
      // this.shardupload(file, shardSize, shardCount, 0, fileList)
      // return false
      return true
    } else {
      return true
    params.file.fileName = file.name.replace(/\.{1}[^.]*$/ig, '')  // 文件名(去除后缀名)
    params.file.fileType = file.name.replace(/^.*\.{1}/ig, '')     // 文件类型
    params.file.fileSize = file.size                               // 文件大小
    params.file.fileChunks = chunks                                // 记录所有chunks的长度
    totalFileReader.readAsArrayBuffer(file)
    totalFileReader.onload = (e) => {   // 对整个totalFile生成md5
      spark.append(e.target.result)
      params.file.fileMd5 = spark.end() // 计算整个文件的fileMd5
      Api.getFilePreUpload({fileMd5: params.file.fileMd5}).then(res => {
        if (res.status && res.urlPath) {
          this.onUpdate(res.urlPath)
          this.setState({
            percent: 100
          }, () => {
            setTimeout(() => {
              this.setState({
                showprogress: false,
                percent: 0
              })
            }, 200)
          })
        } else if (res.shardings && res.shardings.length > 0) {
          res.shardings.forEach(shard => {
            if (shard.shardingNo && parseInt(shard.shardingNo) > currentChunk) {
              currentChunk = parseInt(shard.shardingNo)
            }
          })
          loadNext()
        } else {
          loadNext()
        }
      })
    }
    chunkFileReader.onload = (e) => {
      spark.append(e.target.result)      // 对每一片分片进行md5加密
      params.chunks[params.chunks.length - 1].chunkMd5 = spark.end() // 添加切片md5
      currentChunk++  // 每一次分片onload,currentChunk都需要增加,以便来计算分片的次数
      if (currentChunk < chunks) { // 当前切片总数没有达到总数时
        loadNext()
      } else {
        this.shardupload(params)
      }
    }
    chunkFileReader.onerror = () => {
      this.onDelete()
      console.warn('File reading failed.')
    }
    totalFileReader.onerror = () => {
      this.onDelete()
    }
    let loadNext = () => {
      let start = currentChunk * chunkSize              // 计算分片的起始位置
      let end = Math.min(file.size, start + chunkSize)  // 计算分片的结束位置
      let obj = {                                       // 每一个分片需要包含的信息
        chunk: currentChunk + 1,
        binary: file.slice(start, end),
        start: start,
        end: end,
        chunks
      }
      params.chunks.push(obj)
      chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
    }
    // loadNext()
    return false
  }
  /**
@@ -164,7 +251,7 @@
      fileList: value,
      action: baseUrl,
      method: 'post',
      multiple: true,
      multiple: false,
      onChange: this.onChange,
      onRemove: this.onRemove,
      data: this.getExtraData,
src/templates/comtableconfig/index.jsx
@@ -737,7 +737,7 @@
    }, () => {
      notification.warning({
        top: 92,
        message: this.state.dict['header.menu.basemsg'],
        message: this.state.dict['model.menu.basemsg'],
        duration: 5
      })
    })
src/templates/formtabconfig/index.jsx
@@ -1206,7 +1206,7 @@
    }, () => {
      notification.warning({
        top: 92,
        message: this.state.dict['header.menu.basemsg'],
        message: this.state.dict['model.menu.basemsg'],
        duration: 5
      })
    })
src/templates/sharecomponent/actioncomponent/verifyexcelin/columnform/index.jsx
@@ -3,8 +3,7 @@
import { Form, Row, Col, Select, Button, Input, InputNumber, Radio } from 'antd'
import './index.scss'
class UniqueForm extends Component {
class ExcelInColumn extends Component {
  static propTpyes = {
    dict: PropTypes.object,         // 字典项
    columns: PropTypes.array,       // 列名集合
@@ -33,7 +32,8 @@
    this.props.form.setFieldsValue({
      Column: record.Column,
      Text: record.Text,
      required: record.required,
      required: record.required || 'true',
      import: record.import || 'true',
      type: record.type
    })
    if (record.type === 'Int' || /^Decimal/ig.test(record.type)) {
@@ -92,6 +92,7 @@
          Column: '',
          Text: '',
          required: 'true',
          import: 'true',
          type: 'Nvarchar(50)'
        })
      }
@@ -159,6 +160,7 @@
                  <Select.Option value="Decimal(18,2)"> Decimal(18,2) </Select.Option>
                  <Select.Option value="Decimal(18,4)"> Decimal(18,4) </Select.Option>
                  <Select.Option value="Decimal(18,6)"> Decimal(18,6) </Select.Option>
                  <Select.Option value="date"> date </Select.Option>
                </Select>
              )}
            </Form.Item>
@@ -174,6 +176,18 @@
                initialValue: 'true'
              })(
                <Radio.Group disabled={this.state.locked}>
                  <Radio value="true">{dict['model.true']}</Radio>
                  <Radio value="false">{dict['model.false']}</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
          <Col span={7}>
            <Form.Item label={dict['model.import']}>
              {getFieldDecorator('import', {
                initialValue: 'true'
              })(
                <Radio.Group>
                  <Radio value="true">{dict['model.true']}</Radio>
                  <Radio value="false">{dict['model.false']}</Radio>
                </Radio.Group>
@@ -200,4 +214,4 @@
  }
}
export default Form.create()(UniqueForm)
export default Form.create()(ExcelInColumn)
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.jsx
@@ -35,7 +35,7 @@
      {
        title: this.props.dict['model.name'],
        dataIndex: 'Text',
        width: '19%',
        width: '15%',
        editable: true
      },
      {
@@ -47,20 +47,27 @@
      {
        title: this.props.dict['model.required'],
        dataIndex: 'required',
        width: '12%',
        width: '10%',
        editable: true,
        render: (text, record) => record.required === 'true' ? this.props.dict['model.true'] : this.props.dict['model.false']
      },
      {
        title: this.props.dict['model.import'],
        dataIndex: 'import',
        width: '10%',
        editable: true,
        render: (text, record) => record.import !== 'false' ? this.props.dict['model.true'] : this.props.dict['model.false']
      },
      {
        title: '最小值',
        dataIndex: 'min',
        width: '12%',
        width: '10%',
        editable: true
      },
      {
        title: '最大值',
        dataIndex: 'max',
        width: '12%',
        width: '10%',
        editable: true
      },
      {
@@ -305,6 +312,7 @@
          Text: col.label,
          type: _type,
          limit: _limit,
          import: 'true',
          required: 'true'
        }
@@ -705,7 +713,7 @@
            <Table
              bordered
              rowKey="uuid"
              className="custom-table"
              className="custom-table excel-custom-table"
              dataSource={verify.columns}
              columns={excelColumns}
              pagination={false}
src/templates/sharecomponent/actioncomponent/verifyexcelin/index.scss
@@ -49,6 +49,10 @@
  .custom-table .ant-empty {
    margin: 20px 8px!important;
  }
  .excel-custom-table {
    position: relative;
    top: -25px;
  }
  .errorval {
    display: inline-block;
    width: 30px;
@@ -62,9 +66,9 @@
  .ant-tabs-tabpane {
    position: relative;
    .excel-col-add {
      position: absolute;
      right: 0;
      top: 90px;
      position: relative;
      float: right;
      top: -60px;
    }
  }
}
src/templates/sharecomponent/actioncomponent/verifyexcelout/columnform/index.jsx
@@ -1,9 +1,9 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { Form, Row, Col, Button, Input, InputNumber } from 'antd'
import { Form, Row, Col, Button, Input, InputNumber, Radio } from 'antd'
import './index.scss'
class UniqueForm extends Component {
class ExcelOutColumn extends Component {
  static propTpyes = {
    dict: PropTypes.object,         // 字典项
    columns: PropTypes.array,       // 列名集合
@@ -23,6 +23,7 @@
      Column: record.Column,
      Text: record.Text,
      Width: record.Width,
      export: record.export || 'true'
    })
  }
@@ -41,6 +42,7 @@
          Column: '',
          Text: '',
          Width: 20,
          export: 'true'
        })
      }
    })
@@ -107,10 +109,22 @@
              保存
            </Button>
          </Col>
          <Col span={7}>
            <Form.Item label={dict['model.export']}>
              {getFieldDecorator('export', {
                initialValue: 'true'
              })(
                <Radio.Group>
                  <Radio value="true">{dict['model.true']}</Radio>
                  <Radio value="false">{dict['model.false']}</Radio>
                </Radio.Group>
              )}
            </Form.Item>
          </Col>
        </Row>
      </Form>
    )
  }
}
export default Form.create()(UniqueForm)
export default Form.create()(ExcelOutColumn)
src/templates/sharecomponent/actioncomponent/verifyexcelout/index.jsx
@@ -21,17 +21,24 @@
      {
        title: this.props.dict['model.form.field'],
        dataIndex: 'Column',
        width: '25%'
        width: '20%'
      },
      {
        title: this.props.dict['model.name'],
        dataIndex: 'Text',
        width: '25%'
        width: '20%'
      },
      {
        title: this.props.dict['model.export'],
        dataIndex: 'export',
        width: '20%',
        editable: true,
        render: (text, record) => record.export !== 'false' ? this.props.dict['model.true'] : this.props.dict['model.false']
      },
      {
        title: this.props.dict['model.form.columnWidth'],
        dataIndex: 'Width',
        width: '25%'
        width: '20%'
      },
      {
        title: '操作',
@@ -49,7 +56,7 @@
                cancelText={this.props.dict['model.cancel']}
                onConfirm={() => this.handleDelete(record, 'columns')
              }>
                <span style={{color: '#1890ff', cursor: 'pointer'}}><Icon type="delete" /></span>
                <span style={{color: '#ff4d4f', cursor: 'pointer'}}><Icon type="delete" /></span>
              </Popconfirm>
            </div>
          )
src/templates/sharecomponent/columncomponent/columnform/index.jsx
@@ -264,7 +264,7 @@
    let _param = {
      func: 'sPC_Get_FunMenu',
      ParentID: targetOption.value,
      systemType: options.systemType,
      systemType: options.sysType,
      debug: 'Y'
    }
src/templates/sharecomponent/columncomponent/index.jsx
@@ -103,7 +103,7 @@
        let _param = {
          func: 'sPC_Get_FunMenu',
          ParentID: card.linkmenu[0],
          systemType: options.systemType,
          systemType: options.sysType,
          debug: 'Y'
        }
src/templates/subtableconfig/index.jsx
@@ -640,7 +640,7 @@
    }, () => {
      notification.warning({
        top: 92,
        message: this.state.dict['header.menu.basemsg'],
        message: this.state.dict['model.menu.basemsg'],
        duration: 5
      })
    })
src/templates/treepageconfig/index.jsx
@@ -520,7 +520,7 @@
    }, () => {
      notification.warning({
        top: 92,
        message: this.state.dict['header.menu.basemsg'],
        message: this.state.dict['model.menu.basemsg'],
        duration: 5
      })
    })
src/utils/utils.js
@@ -633,6 +633,13 @@
  static getExcelInSql (item, data, dict) {
    let btn = item.verify
    let keys = ['delete', 'drop', 'insert', 'truncate', 'update']
    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 errors = []
    let _topline = btn.range || 0
@@ -648,22 +655,28 @@
        if (script.position === 'init') {
          _initCustomScript += `
          ${script.sql}
          `
        /* 自定义脚本 */
        ${script.sql}
        `
        } else if (script.position === 'front') {
          _prevCustomScript += `
          ${script.sql}
          `
        /* 自定义脚本 */
        ${script.sql}
        `
        } else {
          _backCustomScript += `
          ${script.sql}
          `
        /* 自定义脚本 */
        ${script.sql}
        `
        }
      })
    }
    let _Ltext = data.map((item, lindex) => {
      let vals = btn.columns.map((col, cindex) => {
      let vals = []
      btn.columns.forEach((col, cindex) => {
        if (col.import === 'false') return
        let val = item[col.Column] !== undefined ? item[col.Column] : ''
        let _position = (_topline + lindex + 1) + dict['main.excel.line'] + ' ' + (cindex + 1) + dict['main.excel.column']  + ' '
@@ -732,9 +745,28 @@
              errors.push(_error)
            }
          }
        } else if (col.type === 'date') {
          val = val.replace(/(^\s*$)|\t*|\v*/ig, '')
          if (!val && col.required === 'true') { // 必填校验
            let _error =  _position + dict['main.excel.content.emptyerror']
            errors.push(_error)
          } else {                               // 关键字校验
            keys.forEach(key => {
              let _patten = new RegExp('(^' + key + '\\s+)|(\\s+' + key + '\\s+)', 'ig')
              if (_patten.test(val)) {
                let _error = _position + dict['main.excel.includekey'] + key
                errors.push(_error)
              }
            })
          }
        }
        return `'${val}' as ${col.Column}`
        if (col.type === 'date') {
          vals.push(`case when ${col.Column}='' then '1900-01-01' else dateadd(day,cast('${val}' as int)-2,'1900-01-01') end as ${col.Column}`)
        } else {
          vals.push(`'${val}' as ${col.Column}`)
        }
      })
      let _lineIndex = '0000' + (lindex + 1) + '0'
@@ -745,9 +777,14 @@
      return `Select ${vals.join(',')}`
    })
    _Ltext = _Ltext.join(' Union all ')
    let result = []
    for(let i = 0; i < _Ltext.length; i += 20) {
      result.push(_Ltext.slice(i, i + 20))
    }
    let _sql = ''
    let _sqlInsert = ''
    let _sqlBottom = ''
    if (item.intertype === 'inner' && !item.innerFunc) {
      let _uniquesql = ''
@@ -756,9 +793,8 @@
          if (unique.status === 'false') return
          let _fields = unique.field.split(',')
          let _fields_ = _fields.map(_field => {
            return `a.${_field}=b.${_field}`
          })
          let _fields_ = _fields.map(_field => `a.${_field}=b.${_field}`)
          let _afields = _fields.map(_field => `a.${_field}`)
          _fields_ = _fields_.join(' and ')
          if (unique.verifyType !== 'physical') {
@@ -766,81 +802,88 @@
          }
          _uniquesql += `
          Set @tbid=''
          Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${unique.field} from @${item.sheet} ) a group by ${unique.field} having sum(n)>1
          If @tbid!=''
          Begin
            select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 重复'
            goto aaa
          end
          Set @tbid=''
          Select top 1 @tbid=${_fields.join('+\' \'+')} from  @${item.sheet} a
          Inner join ${item.sheet} b on ${_fields_}
          If @tbid!=''
          Begin
            select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 与已有数据重复'
            goto aaa
          end
          `
        /* 重复性验证 */
        Set @tbid=''
        Select top 1 @tbid=${_fields.join('+\' \'+')} from (select 1 as n,${unique.field} from @${item.sheet} ) a group by ${unique.field} having sum(n)>1
        If @tbid!=''
        Begin
          select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 重复'
          goto aaa
        end
        Set @tbid=''
        Select top 1 @tbid=${_afields.join('+\' \'+')} from  @${item.sheet} a Inner join ${item.sheet} b on ${_fields_}
        If @tbid!=''
        Begin
          select @ErrorCode='${unique.errorCode}',@retmsg=@tbid+' 与已有数据重复'
          goto aaa
        end
        `
        })
        if (_uniquesql) {
          _uniquesql = 'Declare @tbid Nvarchar(512)' + _uniquesql
        }
      }
      let declarefields = []
      let fields = []
      btn.columns.forEach(col => {
        declarefields.push(`${col.Column} ${col.type}`)
        if (col.type === 'date') {
          declarefields.push(`${col.Column} Nvarchar(50)`)
        } else {
          declarefields.push(`${col.Column} ${col.type}`)
        }
        fields.push(col.Column)
      })
      fields = fields.join(',')
      let _insert = ''
      if (_prevCustomScript) {
        _insert += _prevCustomScript
      }
      if (btn.default !== 'false') {
        _insert += `
        _insert = `
        /* 默认sql */
        Insert into ${item.sheet} (${fields},createuserid,createuser,createstaff,bid) 
        Select ${fields},@userid@,@username,@fullname,@BID@ From @${item.sheet}
        `
      }
      if (_backCustomScript) {
        _insert += _backCustomScript
      }
      _sql = `declare @${item.sheet} table (${declarefields.join(',')},jskey nvarchar(50) )
      Declare @UserName nvarchar(50),@FullName nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000)
      Select  @ErrorCode='', @retmsg=''
      _sql = `
        /* 系统生成 */
        declare @${item.sheet} table (${declarefields.join(',')},jskey nvarchar(50) )
        Declare @UserName nvarchar(50),@FullName nvarchar(50),@ErrorCode nvarchar(50),@retmsg nvarchar(4000),@tbid Nvarchar(512)
        Select  @ErrorCode='', @retmsg='', @UserName='${userName}', @FullName='${fullName}'
        ${_initCustomScript}
        `
      _sqlInsert = `Insert into  @${item.sheet} (${fields},jskey)`
      _sqlBottom = `
        /* 默认sql */
        delete tmp_excel_in where upid=@upid@
        delete tmp_excel_in where datediff(day,createdate,getdate())>15
        ${_uniquesql}
        ${_prevCustomScript}
        ${_insert}
        ${_backCustomScript}
        Delete @${item.sheet}
        aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
      
      select @UserName=UserName,@FullName=FullName from SUsers where UID=@UserID@
      ${_initCustomScript}
      Insert into  @${item.sheet} (${fields},jskey)
      ${_Ltext}
      ${_uniquesql}
      ${_insert}
      Delete @${item.sheet}
      aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg`
    } else {
      _sql = _Ltext
      let fsql = `${_sql}${_sqlInsert}${_sqlBottom}`
      fsql = fsql.replace(/\n\s{8}/ig, '\n')
      console.log(fsql)
    }
    console.log(_sql)
    return {
      sql: _sql,
      lines: result.map((list, index) => {
        return {
          Ltext: window.btoa(window.encodeURIComponent(list.join(' Union all '))),
          Sort: (index + 1) * 10
        }
      }),
      insert: _sqlInsert,
      bottom: _sqlBottom,
      errors: errors.join('; ')
    }
  }
src/views/login/index.jsx
@@ -58,7 +58,7 @@
  }
  async loginsubmit (param) {
    if (options.systemType === 'local' && !window.GLOB.mainSystemApi) { // 业务系统必须设置单点地址
    if (options.sysType === 'local' && !window.GLOB.mainSystemApi) { // 业务系统必须设置单点地址
      Modal.warning({
        title: '未设置单点服务器地址,请联系管理员!'
      })
@@ -91,7 +91,7 @@
      } else {
        this.props.history.replace('/main')
      }
    } else if (res.ErrCode === 'Need_Get_Appkey' && options.systemType === 'SSO') {
    } else if (res.ErrCode === 'Need_Get_Appkey' && options.sysType === 'SSO') {
      message.warning('应用尚未创建,请向云端同步应用!')
      this.setState({
@@ -110,8 +110,8 @@
    let timeStamp = new Date().getTime()
    let _appId = window.GLOB.appId
    if (options.systemType === 'cloud') { // 云端使用系统配置appid
      _appId = options.AppId
    if (options.sysType === 'cloud') { // 云端使用系统配置appid
      _appId = options.caId
    }
    let str = md5('MK19' + _appId + timeStamp)
@@ -236,7 +236,7 @@
      func: 's_get_app_from_cloud',
      UserName: '',
      Password: '',
      systemType: options.systemType,
      systemType: options.sysType,
      Type: 'X',
      debug: 'Y'
    }
src/views/mobdesign/index.jsx
@@ -121,7 +121,6 @@
  }
  editCard = (element) => {
    console.log(element)
    this.setState({
      editElem: element
    })