king
2024-12-31 cce4ab076f3fa26f393fe4039ef5a891e2e8b2a1
2024-12-31
5个文件已修改
4个文件已添加
548 ■■■■■ 已修改文件
public/index.html 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/billcodeform/index.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/utils-custom.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/syscheck/header/index.jsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/syscheck/header/index.scss 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/syscheck/index.jsx 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/syscheck/index.scss 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html
@@ -60,7 +60,11 @@
      }
      window.mkInfo = function(value, color = '') {
        console.info(value, color)
        if (color) {
          console.info(value, color)
        } else {
          console.info(value)
        }
      }
    </script>
  </head>
src/api/index.js
@@ -736,7 +736,11 @@
          if (res.mksqls) {
            res.mksqls.forEach(n => {
              n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
              window.mkInfo(n)
              if (!res.status) {
                window.mkInfo('%c' + n, 'color: #f5222d')
              } else {
                window.mkInfo(n)
              }
            })
          }
          delete res.mksqls
@@ -1055,7 +1059,11 @@
          if (res.mksqls) {
            res.mksqls.forEach(n => {
              n = n.replace(/(UNION ALL\s+)?SELECT obj_name='[\S\s]+sub_field=''\s+/ig, '')
              window.mkInfo(n)
              if (!res.status) {
                window.mkInfo('%c' + n, 'color: #f5222d')
              } else {
                window.mkInfo(n)
              }
            })
          }
          delete res.mksqls
src/router/index.js
@@ -24,6 +24,7 @@
const RoleManage = asyncLoadComponent(() => import('@/views/rolemanage'))
const SystemFunc = asyncLoadComponent(() => import('@/views/systemfunc'))
const SystemProc = asyncLoadComponent(() => import('@/views/systemproc'))
const SystemCheck = asyncLoadComponent(() => import('@/views/syscheck'))
const MkIframe = asyncLoadComponent(() => import('@/views/mkiframe'))
const routers = [
@@ -53,7 +54,8 @@
  {path: '/iframe/:menuId/:loginUid/:bid', name: 'iframe', component: MkIframe},
  {path: '/view/:menuId', name: 'iframe', component: MkIframe},
  {path: '/view/:menuId/:bid', name: 'iframe', component: MkIframe},
  {path: '/interface', name: 'interface', component: Interface}
  {path: '/interface', name: 'interface', component: Interface},
  {path: '/syscheck', name: 'syscheck', component: SystemCheck}
]
export default class RouteConfig extends Component {
src/templates/zshare/verifycard/billcodeform/index.jsx
@@ -91,6 +91,7 @@
      }, () => {
        this.props.form.setFieldsValue({
          field: record.field,
          Type: record.Type || 4,
          TypeCharOne: record.TypeCharOne,
          ModularCode: record.ModularCode,
          ModularDetailCode: _modularDetailCode,
@@ -174,7 +175,7 @@
          // 设置流水号位数
          let _detail = this.state.modularDetail.filter(item => item.ModularDetailCode === values.ModularDetailCode)[0]
          values.Type = _detail.Type
          values.Type = values.Type || _detail.Type
        } else {
          let _billField = billFields.filter(item => item.field === values.linkField)[0]
          values.linkFieldName = _billField ? _billField.label : ''
@@ -310,7 +311,7 @@
              保存
            </Button>
          </Col>
          {type === '1' ? <Col span={7}>
          <Col span={7}>
            <Form.Item label="位数">
              {getFieldDecorator('Type', {
                initialValue: 4,
@@ -322,7 +323,7 @@
                ]
              })(<InputNumber min={1} max={10} precision={0} onPressEnter={this.handleConfirm}/>)}
            </Form.Item>
          </Col> : null}
          </Col>
          {type === '2' ? <Col span={7}>
            <Form.Item label="凭证标识">
              {getFieldDecorator('ModularDetailCode', {
src/utils/utils-custom.js
@@ -6422,7 +6422,7 @@
  filterComponent(config.components, _mainSearch)
  let keys = sqls.map(item => item.uuid)
  if (keys.length > Array.from(new Set(keys)).length) {
  if (keys.length > Array.from(new Set(keys)).length && !window.GLOB.syscheck) {
    let m = new Map()
    let n = new Map()
    sqls.forEach(item => {
src/views/syscheck/header/index.jsx
New file
@@ -0,0 +1,34 @@
import React, { Component } from 'react'
import avatar from '@/assets/img/avatar.jpg'
import MainLogo from '@/assets/img/main-logo.png'
import './index.scss'
class SysCheckHeader extends Component {
  state = {
    avatar: sessionStorage.getItem('CloudAvatar') || avatar,
    userName: sessionStorage.getItem('CloudUserName'),
    logo: sessionStorage.getItem('CloudLogo') || MainLogo
  }
  render () {
    const { logo } = this.state
    return (
      <header className="sys-header-container">
        <div className="header-logo"><img src={logo} alt=""/></div>
        <div className="title">
          系统检查
        </div>
        <div className="header-user">
          <img src={this.state.avatar} alt=""/>
          <span>
            <span className="username">{this.state.userName}</span>
          </span>
        </div>
      </header>
    )
  }
}
export default SysCheckHeader
src/views/syscheck/header/index.scss
New file
@@ -0,0 +1,57 @@
.sys-header-container {
  width: 100%;
  height: 48px;
  color: rgba(255, 255, 255, 0.65);
  position: fixed;
  top: 0px;
  z-index: 10;
  padding-right: 0px;
  left: 0;
  background: #001529;
  border-bottom: 1px solid #000;
  .header-logo {
    float: left;
    width: 180px;
    line-height: 48px;
    text-align: center;
    padding-left: 5px;
    box-sizing: border-box;
    opacity: 1;
    img {
      max-width: 100%;
      max-height: 40px;
    }
  }
  .header-user {
    float: right;
    line-height: 48px;
    margin-right: 10px;
    img {
      width: 29px;
      height: 29px;
      border-radius: 30px;
      margin-right: 7px;
    }
    span {
      color: #ffffff;
      font-size: 0.95rem;
      .username {
        display: inline-block;
        height: 30px;
        max-width: 95px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
    }
  }
  .title {
    position: absolute;
    left: calc(50% - 36px);
    top: 10px;
    color: #ffffff;
    font-size: 18px;
  }
}
src/views/syscheck/index.jsx
New file
@@ -0,0 +1,326 @@
import React, {Component} from 'react'
import { fromJS } from 'immutable'
import { Spin, notification, Button } from 'antd'
import moment from 'moment'
// import { QuestionCircleOutlined } from '@ant-design/icons'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import { getAllSqls } from '@/utils/utils-custom.js'
import './index.scss'
const Header = asyncComponent(() => import('./header'))
class SysCheck extends Component {
  state = {
    loading: false,
    menulist: [],
    thdMenuList: [],
    applist: [],
    lackmenus: [],
    outmenus: [],
    backmenus: [],
    unablemenus: [],
  }
  sqlmap = null
  repmap = null
  UNSAFE_componentWillMount() {
    document.body.className = ''
    window.GLOB.syscheck = true
  }
  componentDidMount() {
    if (!sessionStorage.getItem('UserID')) {
      this.props.history.replace('/login')
      return
    }
  }
  /**
   * @description 组件销毁,清除state更新
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  getMenus = () => {
    this.setState({
      loading: true
    })
    Api.getCloudConfig({func: 's_get_pc_menus', systemType: window.GLOB.sysType, debug: 'Y'}).then(result => {
      if (result.status) {
        let thdMenuList = []
        let menulist = result.fst_menu.map(fst => {
          let fstItem = {
            MenuID: fst.MenuID,
            MenuName: fst.MenuName,
            children: []
          }
          if (fst.snd_menu) {
            fstItem.children = fst.snd_menu.map(snd => {
              let sndItem = {
                MenuID: snd.MenuID,
                MenuName: snd.MenuName,
                children: []
              }
              if (snd.trd_menu) {
                sndItem.children = snd.trd_menu.map(trd => {
                  let trdItem = {
                    MenuID: trd.MenuID,
                    MenuName: trd.MenuName,
                    MenuNo: trd.MenuNo,
                    pName: fst.MenuName + '-' + snd.MenuName,
                    type: 'CustomPage',
                  }
                  if (trd.PageParam) {
                    try {
                      trd.PageParam = JSON.parse(trd.PageParam)
                      trdItem.type = trd.PageParam.Template || 'CustomPage'
                    } catch (e) {
                    }
                  }
                  thdMenuList.push(trdItem)
                  return trdItem
                })
              }
              return sndItem
            })
          }
          return fstItem
        })
        this.setState({
          menulist,
          thdMenuList
        })
        if (thdMenuList.length === 0) {
          this.setState({
            loading: false
          })
        } else {
          this.sqlmap = new Map()
          this.repmap = new Map()
          this.getMenuParam(fromJS(thdMenuList).toJS())
        }
      } else {
        this.setState({
          loading: false
        })
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
      }
    })
  }
  getAppList = () => {
    let param = {
      func: 's_get_kei'
    }
    this.setState({
      loading: true
    })
    Api.getCloudConfig(param).then(result => {
      if (result.status) {
        let applist = []
        result.data.forEach(item => {
          if (!item.data_detail) return
          item.data_detail.forEach(cell => {
            applist.push({
              ID: cell.d_id,
              name: item.remark,
              typename: cell.typename,
              kei_no: item.kei_no,
              lang: cell.lang,
              menus: []
            })
          })
        })
        if (applist.length === 0) {
          this.setState({
            loading: false
          })
        } else {
          let deffers = applist.map((app, i) =>
            new Promise(resolve => {
              let param = {
                func: 's_get_app_menus',
                TypeCharOne: app.kei_no,
                typename: app.typename,
                LText: `select '${window.GLOB.appkey}'`,
                timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
                lang: app.lang
              }
              param.secretkey = Utils.encrypt(param.LText, param.timestamp)
              setTimeout(() => {
                Api.getCloudConfig(param).then(result => {
                  delete result.ErrCode
                  delete result.ErrMesg
                  if (result.status) {
                    result = {
                      ...app,
                      status: true,
                      menus: []
                    }
                    result.menus.forEach(m => {
                      if (m.menus_rolelist) {
                        try {
                          let pageParam = JSON.parse(window.decodeURIComponent(window.atob(m.menus_rolelist)))
                          if (pageParam.type === 'navbar') {
                            m.type = pageParam.type
                          }
                        } catch(e) {
                        }
                        if (m.type === 'navbar') return
                      }
                      delete m.menus_rolelist
                      result.menus.push(m)
                    })
                  }
                  resolve(result)
                })
              }, 200 * i)
            })
          )
          Promise.all(deffers).then(response => {
            let error = response.filter(cell => !cell.status)
            if (error[0]) {
              notification.warning({
                top: 92,
                message: error[0].message,
                duration: 5
              })
              this.setState({
                loading: false
              })
            } else {
              let list = response.filter(cell => cell.menus.length > 0)
              this.setState({
                loading: false,
                applist: list
              })
            }
          })
        }
      } else {
        this.setState({
          loading: false
        })
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
      }
    })
  }
  getMenuParam = (menus) => {
    const { lackmenus, outmenus, unablemenus, backmenus } = this.state
    let menu = menus.shift()
    const { MenuID } = menu
    let param = {
      func: 'sPC_Get_LongParam',
      MenuID: MenuID
    }
    Api.getCloudConfig(param).then(result => {
      if (result.status) {
        let config = null
        try {
          config = result.LongParam ? JSON.parse(window.decodeURIComponent(window.atob(result.LongParam))) : null
        } catch (e) {
          console.warn('Parse Failure')
          config = null
        }
        if (!config) {
          this.setState({lackmenus: [...lackmenus, menu]})
        } else if (!['CustomPage', 'BaseTable'].includes(config.Template)) {
          this.setState({outmenus: [...outmenus, menu]})
        } else if (config.Template === 'CustomPage' && config.version !== 2.0) {
          menu.version = config.version
          this.setState({outmenus: [...outmenus, menu]})
        } else if (!config.enabled) {
          this.setState({unablemenus: [...unablemenus, menu]})
        } else {
          let sqls = getAllSqls(config)
          let keys = sqls.map(item => item.uuid)
          sqls.forEach(item => {
            if (this.sqlmap.has(item.uuid)) {
              if (!this.repmap.has(item.uuid)) {
                this.repmap.set(item.uuid, menu)
              }
            } else {
              this.sqlmap.set(item.uuid, menu)
            }
          })
          if (keys.length > Array.from(new Set(keys)).length) {
            this.setState({backmenus: [...backmenus, menu]})
          }
        }
      } else {
        notification.warning({
          top: 92,
          message: result.message,
          duration: 5
        })
      }
    })
  }
  render () {
    const { loading } = this.state
    if (!sessionStorage.getItem('UserID')) return null
    return (
      <div className="mk-app-check">
        <Header view="manage" />
        {loading ?
          <div className="loading-mask">
            <Spin size="large" />
          </div> : null
        }
        <div className="view-wrap">
          <div>
            <Button disabled={loading} type="primary" style={{marginRight: '15px'}} onClick={this.getMenus}>检查管理系统菜单</Button>
            <Button disabled={loading} type="primary" onClick={this.getAppList}>检查子应用菜单</Button>
          </div>
        </div>
      </div>
    )
  }
}
export default SysCheck
src/views/syscheck/index.scss
New file
@@ -0,0 +1,100 @@
.mk-app-check {
  background: #fff;
  min-height: 100vh;
  padding: 70px 30px;
  .loading-mask {
    position: fixed;
    top: 0px;
    bottom: 0px;
    left: 0px;
    right: 0px;
    z-index: 2;
    background: rgba(255, 255, 255, 0.35);
    .ant-spin {
      position: absolute;
      left: 50%;
      top: 50%;
    }
  }
  .view-wrap {
    width: 100%;
    position: relative;
    display: flex;
    .left-view {
      flex: 1;
      width: 60%;
      padding-right: 5px;
      .app-table {
        padding-top: 30px;
      }
    }
    .right-view {
      width: 40%;
      padding-left: 20px;
      .app-title {
        font-size: 16px;
        font-weight: 500;
        height: 30px;
        line-height: 30px;
        border-bottom: 1px solid #d8d8d8;
        margin-bottom: 17px;
      }
      .sub-app {
        margin: 10px 10px 25px;
        border: 1px solid #e8e8e8;
        height: 210px;
        border-radius: 4px;
        padding-top: 10px;
        .app-item {
          height: 30px;
          line-height: 30px;
          div {
            display: inline-block;
            white-space: nowrap;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            line-height: 30px;
          }
          .label {
            width: 40%;
            text-align: right;
            color: rgba(0, 0, 0, 0.65);
          }
          .content {
            width: 60%;
            padding-left: 10px;
            color: rgba(0, 0, 0, 0.85);
          }
        }
        .action {
          text-align: right;
          padding: 5px 20px;
          margin-top: 5px;
          border-top: 1px solid #e8e8e8;
          .ant-typography-copy {
            color: #26C281;
          }
        }
      }
    }
  }
  .ant-table-wrapper {
    .ant-table-body {
      border: 1px solid #e8e8e8;
      border-bottom: 0;
      border-radius: 4px;
    }
    .ant-table-tbody {
      > tr.ant-table-row-selected td {
        background: #bae7ff;
      }
    }
  }
}