king
2024-06-14 2c573446cd5059b09c06c8673eaf1f51f43967ce
2024-06-14
24个文件已修改
2个文件已添加
488 ■■■■ 已修改文件
src/api/index.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/elementform/index.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/cardcellcomponent/formconfig.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/options.jsx 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/formconfig.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/editColumn/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/base-table/columns/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/editColumn/index.jsx 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/columns/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/editColumn/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/columns/index.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/card/cardcellList/index.jsx 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/share/normalTable/index.jsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/popview/index.jsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/index.jsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/transmenu/index.jsx 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/design/header/transmenu/index.scss 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tabledesign/index.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js
@@ -115,10 +115,10 @@
          url: _url,
          method: 'get'
        }).then(res => {
          if (res.oa_access_token || res.mini_access_token) {
          if (res.oa_access_token) {
            window.GLOB.accessToken.accessTime = parseInt(new Date().getTime() / 1000)
            window.GLOB.accessToken.oa_access_token = res.oa_access_token
            window.GLOB.accessToken.mini_access_token = res.mini_access_token
            // window.GLOB.accessToken.mini_access_token = res.mini_access_token
          }
          resolve(res)
        })
src/menu/components/card/cardcellcomponent/elementform/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, Radio, Tooltip, InputNumber, Cascader, Popover, message, AutoComplete } from 'antd'
import { Form, Row, Col, Input, Select, Radio, Checkbox, Tooltip, InputNumber, Cascader, Popover, message, AutoComplete } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import { formRule } from '@/utils/option.js'
@@ -228,7 +228,7 @@
      }
    } else if (this.record.eleType === 'formula') {
      if (this.record.eval !== 'func') {
        _options.push('prefix', 'postfix', 'fixStyle', 'alignItems')
        _options.push('prefix', 'postfix', 'fixStyle', 'alignItems', 'evalchars')
      }
      if (this.record.eval === 'true') {
        _options.push('decimal')
@@ -578,6 +578,24 @@
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'checkbox') {
        fields.push(
          <Col span={12} key={index}>
            <Form.Item label={label}>
              {getFieldDecorator(item.key, {
                initialValue: item.initVal,
                rules: [{
                  required: item.required,
                  message: '请选择' + item.label + '!'
                }]
              })(
                <Checkbox.Group style={{whiteSpace: 'nowrap'}}>
                  {item.options.map(option => <Checkbox key={option.value} value={option.value}>{option.text}</Checkbox>)}
                </Checkbox.Group>
              )}
            </Form.Item>
          </Col>
        )
      } else if (item.type === 'color') {
        fields.push(
          <Col span={12} key={index} className="color-form">
src/menu/components/card/cardcellcomponent/formconfig.jsx
@@ -695,6 +695,21 @@
      required: true
    },
    {
      type: 'checkbox',
      key: 'evalchars',
      label: '替换字符',
      initVal: card.evalchars || ['enter', 'space'],
      tooltip: '公式解析后,可替换回车、空格等字符,实现换行、字间距控制等页面效果。',
      required: false,
      options: [{
        value: 'enter',
        text: '回车符'
      }, {
        value: 'space',
        text: '空格'
      }]
    },
    {
      type: 'radio',
      key: 'noValue',
      label: '空值',
src/menu/components/form/simple-form/index.jsx
@@ -7,7 +7,7 @@
import asyncComponent from '@/utils/asyncComponent'
import asyncIconComponent from '@/utils/asyncIconComponent'
import { getModalForm } from '@/templates/zshare/formconfig'
import { resetStyle, getTables, checkComponent } from '@/utils/utils-custom.js'
import { resetStyle, getTables, checkComponent, getInterfaces } from '@/utils/utils-custom.js'
import MKEmitter from '@/utils/events.js'
import Utils from '@/utils/utils.js'
import getWrapForm from './options'
@@ -468,9 +468,9 @@
        _card.setting.supModule = ''
      }
    } else if (res.datatype === 'public') {
      let interfaces = window.GLOB.customMenu.interfaces || []
      let interfaces = getInterfaces()
      let d = interfaces.filter(m => m.uuid === res.publicId && m.status === 'true')[0]
      let d = interfaces.filter(m => m.value === res.publicId)[0]
      if (d) {
        _card.columns = fromJS(d.columns).toJS()
src/menu/components/form/simple-form/options.jsx
@@ -1,4 +1,4 @@
import MenuUtils from '@/utils/utils-custom.js'
import MenuUtils, { getInterfaces } from '@/utils/utils-custom.js'
/**
 * @description Wrap表单配置信息
@@ -45,18 +45,7 @@
    }
  }
  let interfaces = []
  if (menu.interfaces) {
    menu.interfaces.forEach(item => {
      if (item.status === 'true') {
        interfaces.push({
          value: item.uuid,
          label: item.name
        })
      }
    })
  }
  let interfaces = getInterfaces()
  let buttons = []
  if (!wrap.enable || wrap.enable === 'true') {
src/menu/components/table/base-table/columns/editColumn/formconfig.jsx
@@ -442,6 +442,21 @@
      required: true
    },
    {
      type: 'checkbox',
      key: 'evalchars',
      label: '替换字符',
      initVal: card.evalchars || ['enter', 'space'],
      tooltip: '公式解析后,可替换回车、空格等字符,实现换行、字间距控制等页面效果。',
      required: false,
      options: [{
        value: 'enter',
        text: '回车符'
      }, {
        value: 'space',
        text: '空格'
      }]
    },
    {
      type: 'radio',
      key: 'noValue',
      label: '空值',
src/menu/components/table/base-table/columns/editColumn/index.jsx
@@ -95,8 +95,13 @@
      } else if (this.record.perspective === 'linkurl') {
        _options.push('linkurl', 'open')
      }
    } else if (this.record.type === 'formula' && this.record.eval === 'true') {
    } else if (this.record.type === 'formula') {
      if (this.record.eval === 'true') {
      _options.push('decimal')
      }
      if (this.record.eval !== 'func') {
        _options.push('evalchars')
      }
    } else if (this.record.type === 'custom' && this.record.IsSort === 'true') {
      _options.push('sortField')
    }
src/menu/components/table/base-table/columns/index.jsx
@@ -193,10 +193,10 @@
        val = '$Index'
      } else if (column.type === 'formula') {
        val = column.formula
        if (column.eval === 'false') {
          val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
          val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
        }
        // if (column.eval === 'false') {
        //   val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        //   val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
        // }
      }
      return (
        <td style={{...style}} className={className}>
src/menu/components/table/edit-table/columns/editColumn/formconfig.jsx
@@ -832,6 +832,21 @@
      options: fields
    },
    {
      type: 'checkbox',
      key: 'evalchars',
      label: '替换字符',
      initVal: card.evalchars || ['enter', 'space'],
      tooltip: '公式解析后,可替换回车、空格等字符,实现换行、字间距控制等页面效果。',
      required: false,
      options: [{
        value: 'enter',
        text: '回车符'
      }, {
        value: 'space',
        text: '空格'
      }]
    },
    {
      type: 'radio',
      key: 'noValue',
      label: '空值',
src/menu/components/table/edit-table/columns/editColumn/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Form, Row, Col, Input, Select, InputNumber, Radio, Tooltip, Modal, notification, Popover } from 'antd'
import { Form, Row, Col, Input, Select, InputNumber, Radio, Checkbox, Tooltip, Modal, notification, Popover } from 'antd'
import { QuestionCircleOutlined } from '@ant-design/icons'
import Api from '@/api'
@@ -107,8 +107,13 @@
        _options.push('hourFormat')
      }
    }
    if (this.record.type === 'formula' && this.record.eval === 'true') {
    if (this.record.type === 'formula') {
      if (this.record.eval === 'true') {
      _options.push('decimal')
      }
      if (this.record.eval !== 'func') {
        _options.push('evalchars')
      }
    } else if (this.record.type === 'custom' && this.record.IsSort === 'true') {
      _options.push('sortField')
    }
@@ -402,6 +407,15 @@
        content = <Radio.Group onChange={(e) => {this.typeChange(item.key, e.target.value)}}>
          {item.options.map(option => <Radio key={option.value} value={option.value}>{option.text}</Radio>)}
        </Radio.Group>
      } else if (item.type === 'checkbox') {
        rules = [
          { required: item.required, message: '请选择' + item.label + '!' }
        ]
        initVal = item.initVal
        content = <Checkbox.Group onChange={(e) => {this.typeChange(item.key, e.target.value)}}>
          {item.options.map(option => <Checkbox key={option.value} value={option.value}>{option.text}</Checkbox>)}
        </Checkbox.Group>
      } else if (item.type === 'multiselect') { // 多选
        content = <Select
          showSearch
src/menu/components/table/edit-table/columns/index.jsx
@@ -195,10 +195,10 @@
        val = '$Index'
      } else if (column.type === 'formula') {
        val = column.formula
        if (column.eval === 'false') {
          val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
          val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
        }
        // if (column.eval === 'false') {
        //   val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        //   val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
        // }
      }
      return (
        <td style={style} className={className}>
src/menu/components/table/normal-table/columns/editColumn/formconfig.jsx
@@ -513,6 +513,21 @@
      required: true
    },
    {
      type: 'checkbox',
      key: 'evalchars',
      label: '替换字符',
      initVal: card.evalchars || ['enter', 'space'],
      tooltip: '公式解析后,可替换回车、空格等字符,实现换行、字间距控制等页面效果。',
      required: false,
      options: [{
        value: 'enter',
        text: '回车符'
      }, {
        value: 'space',
        text: '空格'
      }]
    },
    {
      type: 'radio',
      key: 'noValue',
      label: '空值',
src/menu/components/table/normal-table/columns/editColumn/index.jsx
@@ -94,8 +94,13 @@
      } else if (this.record.perspective === 'linkurl') {
        _options.push('linkurl', 'open')
      }
    } else if (this.record.type === 'formula' && this.record.eval === 'true') {
    } else if (this.record.type === 'formula') {
      if (this.record.eval === 'true') {
      _options.push('decimal')
      }
      if (this.record.eval !== 'func') {
        _options.push('evalchars')
      }
    } else if (this.record.type === 'custom' && this.record.IsSort === 'true') {
      _options.push('sortField')
    } else if (this.record.type === 'extend') {
src/menu/components/table/normal-table/columns/index.jsx
@@ -195,10 +195,10 @@
        val = '$Index'
      } else if (column.type === 'formula') {
        val = column.formula
        if (column.eval === 'false') {
          val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
          val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
        }
        // if (column.eval === 'false') {
        //   val = val.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        //   val = <span style={{fontWeight: 'inherit'}} dangerouslySetInnerHTML={{__html: val}}></span>
        // }
      }
      return (
        <td style={{...style}} className={className}>
src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -991,8 +991,10 @@
  
        if (val !== '') {
          if (val && typeof(val) === 'string') {
            if (!card.evalchars || card.evalchars.includes('enter')) {
            val = val.replace(/\n/ig, '<br/>')
            if (!/<(span|div|p|a|img)\s/g.test(val)) {
            }
            if ((!card.evalchars || card.evalchars.includes('space')) && !/<(span|div|p|a|img)\s/g.test(val)) {
              val = val.replace(/\s/ig, '&nbsp;')
            }
src/tabviews/custom/components/share/normalTable/index.jsx
@@ -446,7 +446,12 @@
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      } else if (content !== '') {
        content = `${col.prefix || ''}${content}${col.postfix || ''}`
        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        if (!col.evalchars || col.evalchars.includes('enter')) {
          content = content.replace(/\n/ig, '<br/>')
        }
        if (!col.evalchars || col.evalchars.includes('space')) {
          content = content.replace(/\s/ig, '&nbsp;')
        }
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      }
src/tabviews/custom/components/table/edit-table/normalTable/index.jsx
@@ -978,7 +978,12 @@
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      } else if (content !== '') {
        content = `${col.prefix || ''}${content}${col.postfix || ''}`
        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        if (!col.evalchars || col.evalchars.includes('enter')) {
          content = content.replace(/\n/ig, '<br/>')
        }
        if (!col.evalchars || col.evalchars.includes('space')) {
          content = content.replace(/\s/ig, '&nbsp;')
        }
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      }
@@ -1292,7 +1297,12 @@
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      } else if (content !== '') {
        content = `${col.prefix || ''}${content}${col.postfix || ''}`
        content = content.replace(/\n/ig, '<br/>').replace(/\s/ig, '&nbsp;')
        if (!col.evalchars || col.evalchars.includes('enter')) {
          content = content.replace(/\n/ig, '<br/>')
        }
        if (!col.evalchars || col.evalchars.includes('space')) {
          content = content.replace(/\s/ig, '&nbsp;')
        }
        content = <span dangerouslySetInnerHTML={{__html: content}}></span>
      }
src/tabviews/custom/index.jsx
@@ -791,6 +791,9 @@
          return cell.eleType !== 'button' || pass || permAction[cell.uuid] || cell.permission === 'false'
        })
      } else if (item.type === 'form') {
        if (item.wrap.datatype === 'public') {
          balMap.set(item.wrap.publicId + 'public', true)
        }
        item.subcards = item.subcards.map(group => {
          group.subButton.uuid = group.uuid
          group.subButton.OpenType = 'formSubmit'
src/tabviews/custom/popview/index.jsx
@@ -513,6 +513,9 @@
          return true
        })
      } else if (item.type === 'form') {
        if (item.wrap.datatype === 'public') {
          balMap.set(item.wrap.publicId + 'public', true)
        }
        item.subcards = item.subcards.map(group => {
          group.subButton.uuid = group.uuid
          group.subButton.OpenType = 'formSubmit'
src/utils/utils-custom.js
@@ -2080,25 +2080,16 @@
 * @description 获取语言转换信息
 */
export function getLangTrans (config) {
  let defLang = window.GLOB.defLang || ''
  let langList = sessionStorage.getItem('langList')
  
  if (langList) {
  if (!langList) return
  let defLang = ''
    try {
      langList = JSON.parse(langList)
      if (langList.length === 1) {
        defLang = ''
      } else if (!defLang || langList.findIndex(item => item.Lang === defLang) === -1) {
        if (langList.findIndex(item => item.Lang === 'zh-CN') === -1) {
          defLang = langList[0].Lang
        } else {
          defLang = 'zh-CN'
        }
      }
    defLang = langList[0]
    } catch (e) {
      defLang = ''
    }
  } else {
    defLang = ''
  }
@@ -2110,7 +2101,7 @@
  let text = []
  let filterElement = (card) => {
    if (card.datatype === 'static' && card.eleType === 'text') {
    if (card.datatype === 'static' && card.eleType === 'text' && !/@.+@/g.test(card.value)) {
      sql.push(card.value)
    }
    if (card.prefix) {
@@ -2362,15 +2353,35 @@
    list.unshift(`'${config.MenuName}','menu'`)
  }
  if (config.fstMenuId && config.parentId) {
    let menulist = sessionStorage.getItem('fstMenuList')
    try {
      menulist = JSON.parse(menulist)
    } catch(e) {
      menulist = []
    }
    menulist.forEach(item => {
      if (item.MenuID !== config.fstMenuId) return
      list.unshift(`'${item.MenuName}','menu'`)
      item.children.forEach(cell => {
        if (cell.MenuID !== config.parentId) return
        list.unshift(`'${cell.MenuName}','menu'`)
      })
    })
  }
  let result = []
  langList.forEach(lan => {
    if (lan.Lang === defLang) return
    if (lan === defLang) return
    list.forEach(n => {
      result.push(`'${lan.Lang}',${n}`)
      result.push(`'${lan}',${n}`)
    })
  })
  
  config.trans = true
  return result.join(';')
}
src/views/design/header/index.jsx
@@ -16,6 +16,8 @@
const VersionsUp = asyncComponent(() => import('./versions'))
const ThawMenu = asyncComponent(() => import('@/components/thawmenu'))
const MenuForm = asyncComponent(() => import('./editfirstmenu/menuform'))
const TransMenu = asyncComponent(() => import('./transmenu'))
const { confirm } = Modal
class Header extends Component {
@@ -24,6 +26,7 @@
    userName: sessionStorage.getItem('CloudUserName'),
    avatar: Utils.getrealurl(sessionStorage.getItem('CloudAvatar')),
    logo: sessionStorage.getItem('CloudLogo') || MainLogo,
    subLang: sessionStorage.getItem('subLangList') !== null,
    visible: false,
    loading: false
  }
@@ -409,7 +412,7 @@
  render () {
    const { mainMenu, editLevel } = this.props
    const { menulist, visible, loading, logo } = this.state
    const { menulist, visible, loading, logo, subLang } = this.state
    return (
      <header className={'sys-header-container ant-menu-dark ' + (['level2', 'level3'].includes(editLevel) ? 'mask' : '')} id="main-header-container">
@@ -493,6 +496,12 @@
              编辑
            </Button>
          </div> : null}
          {window.GLOB.systemType !== 'production' && subLang ? <div className="entrance">
            <div className="icon"><PlusOutlined /></div>
            <div className="title">添加菜单</div>
            <div className="detail">可选择母语系统的菜单,快速转换为当前语言。</div>
            <TransMenu reload={this.reload} menulist={menulist}/>
          </div> : null}
        </div>
        {/* 编辑菜单 */}
        {editLevel === 'level1' ? <EditMenu menulist={this.state.menulist} reload={this.reload} exitEdit={this.exitEdit}/> : null}
src/views/design/header/transmenu/index.jsx
New file
@@ -0,0 +1,194 @@
import React, { Component } from 'react'
import { is, fromJS } from 'immutable'
import { Modal, notification, Button, Spin, Cascader } from 'antd'
// import { ClockCircleOutlined, SyncOutlined, WarningOutlined, CheckCircleOutlined } from '@ant-design/icons'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import './index.scss'
class TransMenu extends Component {
  state = {
    visible: false,
    loading: false,
    lang: '',
    dicts: [],
    menus: [],
    values: []
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
  }
  trigger = () => {
    let langs = sessionStorage.getItem('subLangList')
    langs = JSON.parse(langs)
    this.setState({
      lang: langs[0],
      loading: true,
      visible: true,
      values: []
    })
    this.getDicts()
    this.getMenus(langs[0])
  }
  getDicts = () => {
    // let sql = `select id,lang,lang_name,mother_tongue,translation,use_type,case when use_type='menu' then '菜单' when  use_type='button' then '按钮'  when  use_type='title' then '标题'   when  use_type='list' then '选项' else '文本' end as use_type_text from s_app_lang_translation where appkey=@appkey@ and deleted=0 and translation != ''`
    let sql = `select mother_tongue as reg,translation as value,use_type as type,case when use_type='menu' then '菜单' when  use_type='button' then '按钮'  when  use_type='title' then '标题'   when  use_type='list' then '选项' else '文本' end as use_type_text from s_app_lang_translation where appkey=@appkey@ and deleted=0 and translation != '' and lang='${sessionStorage.getItem('lang') || ''}'`
    let param = {
      func: 'sPC_Get_SelectedList',
      LText: Utils.formatOptions(sql, 'x'),
      obj_name: 'data',
      arr_field: 'reg,value,type',
      exec_type: 'x'
    }
    param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
    param.secretkey = Utils.encrypt('', param.timestamp)
    param.open_key = Utils.encryptOpenKey(param.secretkey, param.timestamp)
    Api.getCloudConfig(param).then(result => {
      if (!result.status) {
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
        return
      }
      this.setState({dicts: result.data || []})
    })
  }
  getMenus = (lang) => {
    let _param = {
      func: 's_get_pc_menus',
      systemType: window.GLOB.sysType,
      pro_sys: '',
      lang: lang,
      debug: 'Y'
    }
    Api.getCloudConfig(_param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
      let menus = []
      res.fst_menu && res.fst_menu.forEach(fst => {
        let fstItem = {
          value: fst.MenuID,
          label: fst.MenuName,
          children: []
        }
        fst.snd_menu && fst.snd_menu.forEach(snd => {
          let sndItem = {
            value: snd.MenuID,
            label: snd.MenuName,
            children: []
          }
          snd.trd_menu && snd.trd_menu.forEach(trd => {
            let trdItem = {
              value: trd.MenuID,
              label: trd.MenuName,
              MenuNo: trd.MenuNo,
            }
            if (!trd.PageParam) return
            let PageParam = null
            try {
              PageParam = JSON.parse(trd.PageParam)
            } catch (e) {
              PageParam = null
            }
            if (!PageParam || !['BaseTable', 'CustomPage'].includes(PageParam.Template)) return
            trdItem.PageParam = PageParam
            sndItem.children.push(trdItem)
          })
          if (sndItem.children.length === 0) return
          fstItem.children.push(sndItem)
        })
        if (fstItem.children.length === 0) return
        menus.push(fstItem)
      })
      this.setState({menus: menus, loading: false})
    })
  }
  submit = () => {
    const { menulist } = this.props
    const { values } = this.state
    if (!values || values.length !== 3) {
      notification.warning({
        top: 92,
        message: '请选择三级菜单!',
        duration: 5
      })
      return
    }
    console.log(values)
    console.log(menulist)
  }
  cancel = () => {
    this.setState({
      loading: false,
      visible: false
    })
  }
  render () {
    const { visible, loading, menus } = this.state
    return (
      <>
        <Button type="primary" onClick={this.trigger}>
          添加
        </Button>
        <Modal
          wrapClassName="sync-menu-modal"
          title="添加菜单"
          visible={visible}
          width={800}
          closable={false}
          maskClosable={false}
          onOk={this.submit}
          onCancel={this.cancel}
          destroyOnClose
        >
          {loading ? <Spin /> : <div>
            <Cascader onChange={(val) => this.setState({values: val})} options={menus} expandTrigger="hover" placeholder="请选择模板菜单"/>
          </div>}
        </Modal>
      </>
    )
  }
}
export default TransMenu
src/views/design/header/transmenu/index.scss
New file
@@ -0,0 +1,16 @@
.sync-menu-modal {
  .ant-modal-body {
    position: relative;
    padding: 24px 50px;
    min-height: 200px;
    max-height: calc(100vh - 210px);
    .ant-cascader-picker {
      width: 300px;
    }
    .ant-spin {
      position: absolute;
      left: 50%;
      top: 75px;
    }
  }
}
src/views/login/index.jsx
@@ -700,7 +700,23 @@
              localStorage.removeItem(_loginurl)
            }
            sessionStorage.setItem('langList', JSON.stringify(res.lang_data || []))
            if (res.lang_data && res.lang_data.length > 1 && window.GLOB.systemType !== 'production') {
              let list = res.lang_data.map(item => item.Lang)
              let lang = 'zh-CN'
              if (window.GLOB.defLang && list.includes(window.GLOB.defLang)) {
                lang = window.GLOB.defLang
              }
              if (list.includes(lang)) {
                list = [lang, ...list.filter(item => item !== lang)]
                if (lang === sessionStorage.getItem('lang')) {
                  sessionStorage.setItem('langList', JSON.stringify(list))
                  sessionStorage.removeItem('subLangList')
                } else {
                  sessionStorage.setItem('subLangList', JSON.stringify(list))
                  sessionStorage.removeItem('langList')
                }
              }
            }
            
            this.setState({
              loginWays: login_ways,
src/views/menudesign/index.jsx
@@ -773,6 +773,9 @@
      })
      return
    } else if (this.checklog()) {
      if (MenuType !== 'billPrint' && sessionStorage.getItem('langList') && !config.trans) {
      } else {
      notification.success({
        top: 92,
        message: '当前配置未修改,无需保存。',
@@ -780,6 +783,7 @@
      })
      MKEmitter.emit('completeSave')
      return
      }
    }
    this.setState({
@@ -842,7 +846,7 @@
      let interfaces = getFuncsAndInters(config)
      let urlFields = config.urlFields ? config.urlFields.join(',') : ''
      let langSql = getLangTrans(config)
      let langSql = MenuType !== 'billPrint' ? getLangTrans(config) : ''
      let param = {
        func: 'sPC_TrdMenu_AddUpt',
src/views/tabledesign/index.jsx
@@ -533,6 +533,9 @@
    if (!this.checkBase()) {
      return
    } else if (this.checklog()) {
      if (sessionStorage.getItem('langList') && !config.trans) {
      } else {
      notification.success({
        top: 92,
        message: '当前配置未修改,无需保存。',
@@ -541,6 +544,7 @@
      MKEmitter.emit('completeSave')
      return
    }
    }
    this.setState({
      menuloading: true