| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import {connect} from 'react-redux' |
| | | import { is, fromJS } from 'immutable' |
| | | import { notification, Spin} from 'antd' |
| | | import { notification, Spin, Modal } from 'antd' |
| | | |
| | | import Api from '@/api' |
| | | import zhCN from '@/locales/zh-CN/main.js' |
| | | import enUS from '@/locales/en-US/main.js' |
| | | import Utils from '@/utils/utils.js' |
| | | import options from '@/store/options.js' |
| | | import UtilsDM from '@/utils/utils-datamanage.js' |
| | | import { updateSubTabTable } from '@/utils/utils-update.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | |
| | | } |
| | | |
| | | state = { |
| | | dict: sessionStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | loadingview: true, // 页面加载中 |
| | | viewlost: false, // 页面丢失:1、未获取到配置-页面丢失;2、页面未启用 |
| | | lostmsg: '', // 页面丢失时的提示信息 |
| | | config: null, // 页面配置信息,包括按钮、搜索、显示列、标签等 |
| | | searchlist: null, // 搜索条件 |
| | | actions: null, // 按钮集 |
| | | columns: null, // 显示列 |
| | | arr_field: '', // 查询字段集 |
| | | setting: null, // 页面全局设置:数据源、按钮及显示列固定、主键等 |
| | | data: [], // 列表数据集 |
| | | selectedData: [], // 已选表格数据 |
| | |
| | | statFields: [], // 合计字段 |
| | | statFValue: [], // 合计值 |
| | | absFields: [], // 绝对值字段 |
| | | loadCustomApi: true, // 加载外部资源 |
| | | hasReqFields: false |
| | | } |
| | | |
| | | /** |
| | | * @description 获取页面配置信息 |
| | | */ |
| | | async loadconfig () { |
| | | const { permAction, Tab } = this.props |
| | | const { Tab } = this.props |
| | | |
| | | let param = { |
| | | func: 'sPC_Get_LongParam', |
| | |
| | | this.setState({ |
| | | loadingview: false, |
| | | viewlost: true, |
| | | lostmsg: this.state.dict['main.view.unenabled'] |
| | | lostmsg: '抱歉,您访问的页面未启用,请联系管理员。' |
| | | }) |
| | | return |
| | | } |
| | |
| | | } |
| | | |
| | | // 权限过滤 |
| | | if (!window.GLOB.mkHS) { |
| | | config.action = config.action.filter(item => item.hidden !== 'true' && permAction[item.uuid]) |
| | | } else { |
| | | config.action = config.action.filter(item => item.hidden !== 'true') |
| | | } |
| | | config.action = config.action.filter(item => item.hidden !== 'true') |
| | | |
| | | config.search = Utils.initSearchVal(config.search) |
| | | |
| | | let hasReqFields = false |
| | | config.search.forEach(field => { |
| | | if (field.required) { |
| | | hasReqFields = true |
| | | } |
| | | }) |
| | | Utils.initSearchVal(config) |
| | | |
| | | // 字段权限黑名单 |
| | | let roleId = sessionStorage.getItem('role_id') || '' // 角色ID |
| | |
| | | config.columns.forEach(col => { |
| | | if (col.field) { |
| | | _arrField.push(col.field) |
| | | |
| | | if (col.type === 'number') { |
| | | col.decimal = col.decimal || 0 |
| | | col.round = Math.pow(10, col.decimal) |
| | | |
| | | if (col.format === 'percent') { |
| | | col.decimal = col.decimal > 2 ? col.decimal - 2 : 0 |
| | | } |
| | | } |
| | | |
| | | col.nameField && _arrField.push(col.nameField) // 链接名字段 |
| | | if (col.Hide !== 'true' && col.type === 'number' && col.sum === 'true') { |
| | |
| | | |
| | | let _actions = [] // 工具栏按钮 |
| | | let _operations = [] // 操作列按钮(存在时) |
| | | let colors = { primary: '#1890ff', yellow: '#c49f47', orange: 'orange', danger: '#ff4d4f', green: '#26C281', dgreen: '#32c5d2', purple: '#8E44AD', cyan: '#13c2c2', gray: '#E7E7EF', default: 'rgba(0, 0, 0, 0.65)' } |
| | | |
| | | config.action.forEach(item => { |
| | | item.logLabel = Tab.label + '-' + item.label // 用于sPC_TableData_InUpDe记录操作按钮 |
| | | item.$menuId = this.props.MenuID |
| | | item.$old = true |
| | | |
| | | if (item.OpenType === 'popview') return |
| | | |
| | | if (item.OpenType === 'excelOut') { // 导出 |
| | | item.$menuName = Tab.label |
| | | } |
| | | |
| | | if (item.verify && item.verify.invalid === 'true') { |
| | | if (item.sqlType === 'insert') { |
| | | item.verify.invalid = 'false' |
| | | } else if (item.Ot === 'notRequired') { |
| | | item.verify.invalid = 'false' |
| | | } else if (item.intertype !== 'system' && item.procMode !== 'system') { |
| | | item.verify.invalid = 'false' |
| | | } |
| | | } |
| | | |
| | | if (item.controlField) { |
| | | if (/,/ig.test(item.controlVal)) { |
| | | item.controlVals = item.controlVal.split(',') |
| | | } else { |
| | | item.controlVals = [(item.controlVal || '')] |
| | | } |
| | | } |
| | | |
| | | item.show = 'button' |
| | | |
| | | let _c = item.class ? item.class.replace('border-', '') : '' |
| | | let color = colors[_c] || '#1890ff' |
| | | |
| | | if (item.position === 'toolbar') { |
| | | item.$toolbtn = true |
| | | |
| | | if (item.class === 'default') { |
| | | item.style = {color: 'rgba(0, 0, 0, 0.65)', backgroundColor: '#fff', borderColor: '#d9d9d9', marginRight: '15px'} |
| | | } else if (item.class.indexOf('border') > -1) { |
| | | item.style = {color: color, backgroundColor: '#fff', borderColor: color, marginRight: '15px'} |
| | | } else { |
| | | item.style = {color: item.class === 'gray' ? 'rgba(0, 0, 0, 0.65)' : '#fff', backgroundColor: color, borderColor: color, marginRight: '15px'} |
| | | } |
| | | |
| | | _actions.push(item) |
| | | } else if (item.position === 'grid') { |
| | | item.style = {color: color, backgroundColor: 'transparent', borderColor: 'transparent'} |
| | | _operations.push(item) |
| | | } |
| | | }) |
| | |
| | | config.setting.execute = config.setting.default !== 'false' // 默认sql是否执行,转为boolean 统一格式 |
| | | config.setting.customScript = '' // 自定义脚本 |
| | | |
| | | if (config.setting.interType === 'system' || (config.setting.interType === 'custom' && config.setting.requestMode === 'system')) { |
| | | if (config.setting.interType === 'system') { |
| | | if (config.setting.scripts && config.setting.scripts.length > 0) { |
| | | let _customScript = '' |
| | | config.setting.scripts.forEach(item => { |
| | |
| | | } |
| | | |
| | | if (sessionStorage.getItem('dataM') === 'true') { // 数据权限 |
| | | config.setting.dataresource = config.setting.dataresource.replace(/\$@/ig, '/*') |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$/ig, '*/') |
| | | config.setting.customScript = config.setting.customScript.replace(/\$@/ig, '/*') |
| | | config.setting.customScript = config.setting.customScript.replace(/@\$/ig, '*/') |
| | | config.setting.dataresource = config.setting.dataresource.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/') |
| | | config.setting.customScript = config.setting.customScript.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/') |
| | | } else { |
| | | config.setting.dataresource = config.setting.dataresource.replace(/@\$|\$@/ig, '') |
| | | config.setting.customScript = config.setting.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}'` }, |
| | |
| | | config.setting.dataresource = config.setting.dataresource.replace(cell.reg, cell.value) |
| | | config.setting.customScript = config.setting.customScript.replace(cell.reg, cell.value) |
| | | }) |
| | | } else { |
| | | config.setting.dataresource = '' |
| | | } |
| | | |
| | | if (config.setting.selected !== 'init' && config.setting.selected !== 'always') { |
| | |
| | | } |
| | | } |
| | | |
| | | config.type = 'table' |
| | | config.wrap = { |
| | | show: config.setting.show || '', |
| | | float: config.setting.float || '', |
| | | advanceType: config.setting.advanceType || '', |
| | | advanceWidth: config.setting.advanceWidth || '', |
| | | drawerPlacement: config.setting.drawerPlacement || '', |
| | | searchRatio: config.setting.searchRatio || '', |
| | | searchLwidth: config.setting.searchLwidth, |
| | | borderRadius: config.setting.borderRadius, |
| | | resetContrl: config.setting.resetContrl, |
| | | } |
| | | |
| | | config.setting.arr_field = _arrField.join(',') |
| | | |
| | | this.setState({ |
| | | pageSize: config.setting.pageSize || 10, |
| | | loadingview: false, |
| | |
| | | absFields, |
| | | statFields, |
| | | setting: config.setting, |
| | | searchlist: config.search, |
| | | actions: _actions, |
| | | columns: _columns, |
| | | arr_field: _arrField.join(','), |
| | | search: Utils.initMainSearch(config.search), // 搜索条件初始化(含有时间格式,需要转化) |
| | | hasReqFields |
| | | }, () => { |
| | | if (config.setting.onload !== 'false') { // 初始化可加载 |
| | | this.loadData() |
| | |
| | | } |
| | | |
| | | loadData = (id) => { |
| | | const { setting, search, hasReqFields, loadCustomApi } = this.state |
| | | const { setting, search, config } = this.state |
| | | |
| | | let searches = fromJS(search).toJS() |
| | | |
| | | if (hasReqFields) { |
| | | if (config.$s_req) { |
| | | let requireFields = searches.filter(item => item.required && item.value === '') |
| | | if (requireFields.length > 0) { |
| | | this.setState({ |
| | |
| | | } |
| | | } |
| | | |
| | | if (window.GLOB.systemType === 'production' && setting.interType === 'custom' && !setting.proInterface) { |
| | | if (setting.interType === 'custom') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未设置正式系统地址!', |
| | | message: '系统不在支持自定义接口!', |
| | | duration: 3 |
| | | }) |
| | | return |
| | |
| | | selectedData: [] |
| | | }) |
| | | |
| | | if (setting.interType === 'custom' && loadCustomApi) { |
| | | if (setting.execTime === 'once') { |
| | | this.setState({loadCustomApi: false}) |
| | | } |
| | | |
| | | this.loadOutResource(searches) |
| | | if (setting.execType === 'async') { |
| | | this.loadmaindata(id) |
| | | } |
| | | } else { |
| | | this.loadmaindata(id) |
| | | } |
| | | } |
| | | |
| | | loadOutResource = (searches) => { |
| | | const { setting } = this.state |
| | | |
| | | let param = UtilsDM.getPrevQueryParams(setting, searches, this.props.BID) |
| | | |
| | | if (setting.execType === 'sync') { |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | } |
| | | |
| | | Api.genericInterface(param).then(res => { |
| | | if (res.status) { |
| | | if (res.mk_ex_invoke === 'false' || res.mk_ex_invoke === false) { |
| | | this.loadmaindata() |
| | | } else { |
| | | this.customOuterRequest(res) |
| | | } |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }, () => { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | customOuterRequest = (result) => { |
| | | const { setting } = this.state |
| | | let url = '' |
| | | |
| | | if (window.GLOB.systemType === 'production') { |
| | | url = setting.proInterface |
| | | } else { |
| | | url = setting.interface |
| | | } |
| | | |
| | | let mkey = result.mk_api_key || '' |
| | | |
| | | delete result.mk_ex_invoke |
| | | delete result.status |
| | | delete result.message |
| | | delete result.ErrCode |
| | | delete result.ErrMesg |
| | | delete result.mk_api_key |
| | | |
| | | let param = {} |
| | | |
| | | Object.keys(result).forEach(key => { |
| | | key = key.replace(/^mk_/ig, '') |
| | | param[key] = result[key] |
| | | }) |
| | | |
| | | Api.directRequest(url, setting.method, param, setting.cross).then(res => { |
| | | if (typeof(res) !== 'object') { |
| | | let error = '未知的返回结果!' |
| | | |
| | | if (typeof(res) === 'string') { |
| | | error = res.replace(/'/ig, '"') |
| | | } |
| | | |
| | | let _result = { |
| | | mk_api_key: mkey, |
| | | $ErrCode: 'E', |
| | | $ErrMesg: error |
| | | } |
| | | |
| | | this.customCallbackRequest(_result) |
| | | } else { |
| | | if (Array.isArray(res)) { |
| | | res = { data: res } |
| | | } |
| | | res.mk_api_key = mkey |
| | | this.customCallbackRequest(res) |
| | | } |
| | | }, (e) => { |
| | | let _result = { |
| | | mk_api_key: mkey, |
| | | $ErrCode: 'E', |
| | | $ErrMesg: e && e.statusText ? e.statusText : '' |
| | | } |
| | | |
| | | this.customCallbackRequest(_result) |
| | | }) |
| | | } |
| | | |
| | | customCallbackRequest = (result) => { |
| | | const { setting } = this.state |
| | | let errSql = '' |
| | | if (result.$ErrCode === 'E') { |
| | | errSql = ` |
| | | set @ErrorCode='E' |
| | | set @retmsg='${result.$ErrMesg}' |
| | | ` |
| | | delete result.$ErrCode |
| | | delete result.$ErrMesg |
| | | } |
| | | |
| | | let lines = UtilsDM.getCallBackSql(setting, result) |
| | | let param = {} |
| | | |
| | | if (setting.callbackType === 'script') { // 使用自定义脚本 |
| | | let sql = lines.map(item => (` |
| | | ${item.insert} |
| | | ${item.selects.join(` union all |
| | | `)} |
| | | `)) |
| | | sql = sql.join('') |
| | | |
| | | param = UtilsDM.getCallBackQueryParams(setting, sql, errSql, this.props.BID) |
| | | } else { |
| | | let name = this.props.Tab ? (this.props.Tab.label || '') : '' |
| | | param.func = 's_ex_result_back' |
| | | param.s_ex_result = lines.map((item, index) => ({ |
| | | MenuID: this.props.MenuID, |
| | | MenuName: name, |
| | | TableName: item.table, |
| | | LongText: window.btoa(window.encodeURIComponent(`${item.insert} ${item.selects.join(` union all `)}`)), |
| | | Sort: index + 1 |
| | | })) |
| | | |
| | | if (window.GLOB.debugger === true || (window.debugger === true && options.sysType !== 'cloud')) { |
| | | let sql = lines.map(item => (` |
| | | ${item.insert} |
| | | ${item.selects.join(` union all |
| | | `)} |
| | | `)) |
| | | sql = sql.join('') |
| | | console.info(sql.replace(/\n\s{10}/ig, '\n')) |
| | | } |
| | | } |
| | | |
| | | Api.genericInterface(param).then(res => { |
| | | if (res.status) { |
| | | this.loadmaindata() |
| | | } else { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | }, () => { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }) |
| | | this.loadmaindata(id) |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | async loadmaindata (id) { |
| | | const { BID } = this.props |
| | | const { setting, arr_field, search, orderBy, pageIndex, pageSize, absFields } = this.state |
| | | const { setting, search, orderBy, pageIndex, pageSize, absFields } = this.state |
| | | |
| | | let searches = fromJS(search).toJS() |
| | | |
| | |
| | | }) |
| | | |
| | | let _orderBy = orderBy || setting.order |
| | | let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID) |
| | | let param = UtilsDM.getQueryDataParams(setting, searches, _orderBy, pageIndex, pageSize, BID) |
| | | |
| | | delete param.s_version_up |
| | | |
| | | let result = await Api.genericInterface(param) |
| | | |
| | |
| | | item.$Index = start + index + '' |
| | | |
| | | if (setting.controlField) { |
| | | if (setting.controlVal.includes(item[setting.controlField])) { |
| | | if (setting.controlVal.includes(item[setting.controlField] + '')) { |
| | | item.$disabled = true |
| | | } |
| | | } |
| | |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | if (result.ErrCode === 'N') { |
| | | Modal.error({ |
| | | title: result.message, |
| | | }) |
| | | } else { |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | const { BID } = this.props |
| | | const { setting, orderBy, statFields } = this.state |
| | | |
| | | if (statFields.length === 0 || !(setting.interType === 'system' || (setting.interType === 'custom' && setting.requestMode === 'system')) || !setting.dataresource) return |
| | | if (statFields.length === 0 || setting.interType !== 'system' || !setting.dataresource) return |
| | | |
| | | let _orderBy = orderBy || setting.order |
| | | let param = UtilsDM.getStatQueryDataParams(setting, statFields, searches, _orderBy, BID) |
| | |
| | | */ |
| | | async loadmainLinedata (id) { |
| | | const { BID } = this.props |
| | | const { setting, arr_field, search, orderBy, pageIndex, pageSize, absFields } = this.state |
| | | const { setting, search, orderBy, pageIndex, pageSize, absFields } = this.state |
| | | |
| | | let searches = fromJS(search).toJS() |
| | | |
| | |
| | | }) |
| | | |
| | | let _orderBy = orderBy || setting.order |
| | | let param = UtilsDM.getQueryDataParams(setting, arr_field, searches, _orderBy, pageIndex, pageSize, BID, id) |
| | | let param = UtilsDM.getQueryDataParams(setting, searches, _orderBy, pageIndex, pageSize, BID, id) |
| | | |
| | | delete param.s_version_up |
| | | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | |
| | | * @description 导出Excel时,获取页面搜索排序等参数 |
| | | */ |
| | | queryModuleParam = (menuId, callback) => { |
| | | const { Tab, MenuID } = this.props |
| | | const { arr_field, orderBy, search, setting} = this.state |
| | | const { MenuID } = this.props |
| | | const { orderBy, search, setting} = this.state |
| | | |
| | | if (MenuID !== menuId) return |
| | | |
| | | callback({ |
| | | arr_field: arr_field, |
| | | orderBy: orderBy || setting.order, |
| | | search: search, |
| | | menuName: Tab.label |
| | | search: search |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { config, setting, searchlist, pageSize, actions, columns, loadingview, viewlost, selectedData } = this.state |
| | | const { config, setting, pageSize, actions, columns, loadingview, viewlost, selectedData } = this.state |
| | | |
| | | return ( |
| | | <div className="subtabtable" id={'subtabtable' + this.props.MenuID}> |
| | | {loadingview && <Spin />} |
| | | {searchlist && searchlist.length ? |
| | | <SubSearch BID={this.props.BID} setting={setting} searchlist={searchlist} refreshdata={this.refreshbysearch}/> : null |
| | | {config && config.search && config.search.length ? |
| | | <SubSearch BID={this.props.BID} config={config} refreshdata={this.refreshbysearch}/> : null |
| | | } |
| | | {config ? <div style={{minHeight: '25px'}}> |
| | | <SubAction |
| | |
| | | actions={actions} |
| | | columns={columns} |
| | | BID={this.props.BID} |
| | | dict={this.state.dict} |
| | | BData={this.props.BData} |
| | | selectedData={selectedData} |
| | | MenuID={this.props.SupMenuID} |
| | |
| | | columns={columns} |
| | | pageSize={pageSize} |
| | | data={this.state.data} |
| | | dict={this.state.dict} |
| | | BData={this.props.BData} |
| | | total={this.state.total} |
| | | MenuID={this.props.MenuID} |
| | |
| | | } |
| | | } |
| | | |
| | | const mapStateToProps = (state) => { |
| | | return { |
| | | permAction: state.permAction |
| | | } |
| | | } |
| | | |
| | | const mapDispatchToProps = () => { |
| | | return {} |
| | | } |
| | | |
| | | export default connect(mapStateToProps, mapDispatchToProps)(SubTabModalTable) |
| | | export default SubTabModalTable |