UNPKG

@cainiaofe/cn-ui-lowcode

Version:
1,653 lines (1,612 loc) 65 kB
import React from 'react'; import { CnTable as UICnTable, CnOSSImport, CnExport, CnDownload, Box, CnConfirmButton, CnButton, CnBalloon, CnMessage, } from '@cainiaofe/cn-ui'; import merge from 'lodash/merge'; import { calculateTextExprValue, calculateWaitComponentList, executeEventWithoutJS, executeFunction, executeObjectExpr, getRealizeValue, getRealRequestUrl, handleDesignMokelayUrl, handleI18nLabel, handleListI18nLabel, handleRequestConfig, isArrayNotEmpty, isDesignMode, isEmptyButNotZero, isRequestConfig, renderIcon, setDataToDs, transDataSourceToMap, transProxyToObject, transTextExprToFunction, } from '@/common/util/util'; import { getButtonAction, getItem, getRunTimeItem, } from '@/common/manager/button'; import './view.scss'; import { getRunTimeCell, allCellMap } from '@/common/manager/cell'; import { ButtonPosition } from '@/common/manager/position/button-position'; import { getRealResponse, handleRequestParams, handleResultProcessFunc, makeRequest, transRequestConfigToRemote, } from '@/common/util/request'; import isPlainObject from 'lodash/isPlainObject'; import { _bindFilterData, _columnInfo, _getBindFilterData, _getContext, _getCurrentTableInfo, _selectedRowKeys, _selectedRowRecords, _state, _tableRef, _tableResponse, } from '@/common/util/biz-component-prop-name'; import { __dataSource__, __filterValue__, __formValue__, __paging__, __selectedRowKeys__, __selectedRowRecords__, __tableColumns__, __tableCurrentRow__, __tableData__, __tableExtra__, __totalCount__, } from '@/common/util/expr-const'; import $i18n from 'panda-i18n'; import { dataOriginStatic, formUrlencoded } from '@/common/util/const'; import qs from 'query-string'; import { CnPageRequestFinish, CnTableRequestFinish, emitEvent, onEvent, } from '@/common/util/event-name'; import cloneDeep from 'lodash/cloneDeep'; import set from 'lodash/set'; import isEmpty from 'lodash/isEmpty'; import isEqual from 'lodash/isEqual'; import isObject from 'lodash/isObject'; import isFunction from 'lodash/isFunction'; import { getBizExtendProps } from '@/common/manager/plugin'; class CnTable extends React.Component { constructor(props) { super(props); this.remoteInstance = UICnTable?.createRemoteInstance?.(); const tempState = { allEnumMap: {}, tableDataSource: undefined, hasPermission: true, permissionTip: '', permissionLink: '', childTableOpenKeys: [], }; if (isArrayNotEmpty(props?.openKeys)) { tempState.openKeys = [...props.openKeys]; } const realOpenKeys = this.getOpenKeys(props); if (realOpenKeys) { tempState.childTableOpenKeys = realOpenKeys; } this.state = tempState; this.childTableRemoteInstanceMap = {}; } getOpenKeys(props = this.props) { const { childTable = {}, _context } = props; const openKeysConfig = childTable?.openKeysConfig; const realOpenKeys = isFunction(openKeysConfig) ? openKeysConfig({}, _context?.state) : openKeysConfig; return realOpenKeys; } setTableProps = (config) => { const { dataSource } = config || {}; if (Array.isArray(dataSource)) { this.setState({ tableDataSource: dataSource, }); } }; componentWillReceiveProps(nextProps, nextContext) { // 设计态专用 if (nextProps?.remote?.serviceType === 'tiangong') { if ( nextProps?.remote?.guid && nextProps?.remote?.guid !== this.props?.remote?.guid ) { setTimeout(() => { this.load(); }, 500); } } } reRender = () => { const realOpenKeys = this.getOpenKeys(); if (Array.isArray(realOpenKeys)) { this.setState({ childTableOpenKeys: [...realOpenKeys], }); } else { this.forceUpdate(); } }; componentDidMount() { onEvent(CnPageRequestFinish, () => { const { columns } = this.props; if (isArrayNotEmpty(columns)) { for (const item of columns) { const { dataIndex, format, options = {} } = item || {}; if ( dataIndex && format === 'enumeration' && options?.enumDataOrigin === dataOriginStatic ) { this.reRender(); break; } } } }); } setEnumMap = () => { const isDesign = isDesignMode(this.props); const { _context, columns } = this.props; const enumPromiseList = []; const allEnumMap = {}; if (Array.isArray(columns) && columns.length > 0) { for (const item of columns) { const { dataIndex, format, options = {} } = item || {}; if (dataIndex && format === 'enumeration') { const { enumDataOrigin, enumRequestConfig, enumDataSource } = options; if (enumDataOrigin === 'request' && enumRequestConfig?.url) { enumPromiseList.push( makeRequest({ buttonConfig: { options: { requestConfig: enumRequestConfig, }, }, state: _context?.state, needSuccessToast: false, isDesign, urlParamsDataSource: this.getUrlParams(), }).then((res) => { return { dataIndex, data: getRealResponse(res)?.data, }; }), ); } else if (enumDataOrigin === 'static') { if (Array.isArray(enumDataSource) && enumDataSource?.length > 0) { allEnumMap[dataIndex] = transDataSourceToMap(enumDataSource); } else if (typeof enumDataSource === 'function') { const temp = executeFunction(enumDataSource, _context?.state); if (Array.isArray(temp) && temp?.length > 0) { allEnumMap[dataIndex] = transDataSourceToMap(temp); } } else { const temp = calculateTextExprValue(enumDataSource, { state: _context?.state, }); if (Array.isArray(temp) && temp?.length > 0) { allEnumMap[dataIndex] = transDataSourceToMap(temp); } } } } } if (enumPromiseList.length > 0) { Promise.allSettled(enumPromiseList).then((res) => { if (res.length > 0) { res.forEach((item3) => { if (item3?.value?.dataIndex && item3?.value?.data?.length > 0) { allEnumMap[item3?.value?.dataIndex] = transDataSourceToMap( item3?.value?.data, ); } }); } this.setState({ allEnumMap, }); }); } else if (Object.keys(allEnumMap).length > 0) { this.setState({ allEnumMap, }); } } }; load = () => { this.setState({ tableDataSource: undefined, }); this.remoteInstance?.refresh?.(); }; tableLoad = () => { this.remoteInstance?.load?.(); }; refreshExceptPaging = () => { this.remoteInstance?.refreshExceptPaging?.(); }; getRemoteOperation = () => { return this.remoteInstance?.remoteOperation; }; collectFormatMap = (tableColumns, formatMap) => { if (isArrayNotEmpty(tableColumns)) { tableColumns.forEach((item) => { const { format, dataIndex, children } = item || {}; if (format && !allCellMap[format]) { const componentDefine = getRunTimeCell(format); if (componentDefine) { let { component } = componentDefine; component = getRealizeValue(component); if (component && typeof component === 'function') { formatMap[format] = (column) => { return { cell: (value, index, record) => { const com = React.createElement(component, { [_columnInfo]: column, cellConfig: column, value, record, index, enumMap: this.state.allEnumMap[column?.dataIndex], [_tableRef]: this, // _context, }); if (com) { return com; } return '-'; }, enableAutoWidth: false, }; }; } } } this.collectFormatMap(children, formatMap); }); } }; dynamicRegisterFormat = (data) => { if (data) { const { tableColumns = [] } = data; const formatMap = {}; this.collectFormatMap(tableColumns, formatMap); if (Object.keys(formatMap).length > 0) { UICnTable?.registerFormat(formatMap); } } }; // 处理数据源 handleDesignMode = (tableProps = {}, isDesign) => { if (isDesign) { const { remote } = tableProps; // const newData = {} // if(dataSource.length === 0 && columns.length > 0){ // columns.forEach(item=>{ // const {dataIndex,format} = item; // newData[dataIndex] = 'mock数据' // }) // tableProps.dataSource = [newData] // } // tableProps.remote = {} // 如果table配置了remote,那么强制将dataSource设置为空,并且设置remote.url的域名为预发mokelay的域名 if (remote && remote.url && remote.serviceType === 'mokelay') { tableProps.remote = { ...tableProps.remote, url: handleDesignMokelayUrl(remote.url), }; // tableProps.dataSource = undefined } handleListI18nLabel(tableProps?.columns, 'title'); handleListI18nLabel(tableProps?.operateColumn?.buttons, 'children'); handleListI18nLabel(tableProps?.toolbar?.batchArea, 'children'); handleListI18nLabel(tableProps?.toolbar?.toolArea, 'children'); if (tableProps?.emptyContent) { tableProps.emptyContent = handleI18nLabel(tableProps.emptyContent); } } }; /** * 处理操作列 */ handleColumns = (columns = []) => { const newColumnMap = {}; const result = []; columns.forEach((item) => { const { parent } = item || {}; const newColumn = this.makeColumnItem(item); if (newColumn) { if (newColumn?.dataIndex) { newColumnMap[newColumn.dataIndex] = newColumn; } if (parent && newColumnMap[parent]) { if (Array.isArray(newColumnMap[parent].children)) { newColumnMap[parent].children.push(newColumn); } else { newColumnMap[parent].children = [newColumn]; } } else { result.push(newColumn); } } }); return result; }; makeColumnItem = (item) => { if (item) { const { _context } = this.props; const isDesign = isDesignMode(this.props); const { dataIndex, format, optType, options = {}, cellRender, width, } = item || {}; const result = { ...item, }; if (format === 'date-time') { result.dateHasSecond = true; } if (typeof result.hidden === 'function') { result.hidden = executeFunction(result.hidden, {}, _context?.state); } if (format && format !== 'CnArrayView') { const componentDefine = getRunTimeCell(format); if (componentDefine) { let { component, beforeHandler } = componentDefine; component = getRealizeValue(component); if (typeof beforeHandler === 'function') { beforeHandler?.(result, { _context, }); } else if (component && typeof component === 'function') { result.cell = (value, index, record) => { const com = React.createElement(component, { ...options, cellConfig: item, value, record, index, _context, enumMap: this.state.allEnumMap[dataIndex], [_tableRef]: this, }); if (com) { return com; } return '-'; }; result.enableAutoWidth = false; } } } if (optType) { const action = getButtonAction({ ...item, position: ButtonPosition.tableCell, }); if (action && !isDesign) { result.getCellProps = (value, rawData, rawIndex) => { const temp = {}; if (isEmptyButNotZero(value)) { } else { temp.onClick = () => { if ( optType === 'setFilterValue' || optType === 'dialog' || optType === 'flowAction' || optType === 'formReload' ) { if (isPlainObject(rawData)) { this.setDataSource({ [__tableCurrentRow__]: rawData, }); } } action({ buttonConfig: item, record: rawData, index: rawIndex, value, state: _context?.state, urlParamsDataSource: this.getUrlParams(), recordDataSource: rawData, extraParamList: [rawIndex], _context, position: ButtonPosition.tableCell, }); }; } if (optType) { temp.className = 'cn-table-link-cell'; } return temp; }; } } if (typeof cellRender === 'function') { result.cell = cellRender; } if(typeof width === 'number' && width > 0) { result.sizeFixed = true; } return result; } }; handleOperateButtonExpr = (expr, state) => { if (typeof expr === 'boolean') { return () => { return expr; }; } else if (typeof expr === 'function') { return (record, index) => { // return expr?.(record, state, index); return executeFunction(expr, record, state, index); }; } else if (typeof expr === 'string' && expr.length > 0) { const func = transTextExprToFunction(expr); if (func) { return (record, index) => { return executeFunction( func, record || {}, state?.urlParams || {}, state || {}, ); }; } } else if (isPlainObject(expr)) { return (record, index) => { return executeObjectExpr(expr, { [__tableCurrentRow__]: record || {}, [__dataSource__]: state || {}, }); }; } return expr; }; // // handleToolbarButtonExpr = (expr, state) => { // if (typeof expr === 'boolean') { // return () => { // return expr; // }; // } else if (typeof expr === 'function') { // return () => { // return expr?.(this.getFilterParams(), state); // }; // } else if ((typeof expr === 'string' && expr.length > 0) || isPlainObject(expr)) { // return ()=>{ // const filterParams = this.getFilterParams(); // return executeObjectExpr(expr, { // [__formValue__]: filterParams, // [__filterValue__]: filterParams, // [__dataSource__]: state || {}, // }, filterParams, state || {}) // } // } // return expr; // }; handleOperateButtons = (buttons = [], extraConfig) => { const isDesign = isDesignMode(this.props); const { isInChildTable, record, index: tableInParentIndex, } = extraConfig || {}; const { _context } = this.props; return buttons.map((item) => { const { primaryKey, optType, options = {}, children, hidden, disabled, ...rest } = item; const isHidden = this.handleOperateButtonExpr(hidden, _context?.state); const isDisabled = this.handleOperateButtonExpr( disabled, _context?.state, ); const temp = { ...rest, hidden: isHidden, disabled: isDisabled, children, }; const action = getButtonAction({ ...item, position: ButtonPosition.tableOperate, }); const componentDefine = getRunTimeItem(optType); const { createService, pollingService } = options; if (optType === 'export') { temp.children = (tableCurrentRecord, tableCurrentIndex) => { return ( <CnExport autoDownload buttonText={children} buttonProps={{ text: true, // disabled: isDisabled, type: item?.type, }} showAsyncDialog createService={(fileName) => { let jobName = fileName || {}; if (typeof fileName === 'string') { jobName = { jobName: fileName, }; } return makeRequest({ handleParams: () => { const filterParams = this.getFilterParams(); let temp2 = { ...jobName, }; if (isPlainObject(filterParams)) { temp2 = { ...filterParams, ...temp2, }; } return temp2; }, buttonConfig: { options: { requestConfig: createService, }, }, state: _context?.state, recordDataSource: tableCurrentRecord, urlParamsDataSource: this.getUrlParams(), needSuccessToast: false, extraParamList: [tableCurrentIndex], isDesign, }).then((res) => { return getRealResponse(res)?.data; }); }} pollingService={transRequestConfigToRemote({ requestConfig: pollingService, recordDataSource: tableCurrentRecord, urlParamsDataSource: this.getUrlParams(), extraParamList: [tableCurrentIndex], })} /> ); }; } if (action) { if (!isDesign) { const tempButtonConfig = cloneDeep(item); temp.onClick = (e, record, index) => { if (isPlainObject(record)) { this.setDataSource({ [__tableCurrentRow__]: record, }); } action({ position: ButtonPosition.tableOperate, componentProps: this.props, buttonConfig: tempButtonConfig, e, record, index, _context, tableRef: isInChildTable ? { load: this.childTableRemoteInstanceMap[tableInParentIndex] ?.refresh, tableLoad: this.childTableRemoteInstanceMap[tableInParentIndex] ?.load, } : this, state: _context?.state, urlParamsDataSource: this.getUrlParams(), recordDataSource: record, extraParamList: [index], [_getContext]: () => { return _context; }, }); }; const { needConfirm, confirmInfo } = options || {}; if ( optType === 'request' && needConfirm && confirmInfo?.confirmShowType === 'balloon' ) { const commonParams = this.getCommonParams(); const oldClick = temp.onClick; temp.children = (record, index) => { return ( <CnConfirmButton dialogTitle={calculateTextExprValue( confirmInfo.title, commonParams, )} dialogContent={calculateTextExprValue( confirmInfo.content, commonParams, )} text isBalloon type={'primary'} btnContent={children} balloonProps={{ align: 'tr', }} successMsg={false} onConfirmSuccess={oldClick?.bind(this, null, record, index)} /> ); }; tempButtonConfig.options.needConfirm = false; temp.onClick = undefined; } } } else if (componentDefine?.component) { const component = getRealizeValue(componentDefine.component); if (component) { temp.children = (record, index) => { return React.createElement(component, { ...options, record, index, buttonConfig: item, children, _context, [_tableRef]: this, [_getBindFilterData]: this.getFilterParams, [_getContext]: () => { return _context; }, }); }; } } return temp; }); }; handleRowSelection = (rowSelection) => { const { selectType } = rowSelection || {}; const { _context, value, useDetailValue } = this.props; const result = { ...rowSelection, useDetailValue }; if (typeof result?.isDisabled === 'function') { const originIsDisabledFunc = result.isDisabled; result.isDisabled = ( row, rowIndex, selectedRowKeys, selectedRowRecords, ) => { return originIsDisabledFunc( row, rowIndex, selectedRowKeys, selectedRowRecords, _context?.state, ); }; } else { delete result?.isDisabled; } result.type = selectType; if (isArrayNotEmpty(value)) { result.selectedRowKeys = value; } return result; }; // 处理工具栏按钮 handleToolbar = (toolbar) => { const result = {}; if (toolbar) { const { batchArea = [], toolArea = [], settings = [] } = toolbar; if (batchArea.length > 0) { result.batchArea = batchArea .map((item) => { return this.makeButton(item, ButtonPosition.tableBatchArea); }) .filter((item) => item); } if (toolArea.length > 0) { result.toolArea = toolArea .map((item) => { return this.makeButton(item, ButtonPosition.tableToolArea); }) .filter((item) => item); } if (settings.length > 0) { result.settings = settings; } result.columnChange = (newColumns, method) => { if (method === 'user' && isArrayNotEmpty(newColumns)) { this.setDataSource({ [__tableColumns__]: newColumns, }); } }; } return result; }; getDownloadProps = (data, extraConfig) => { const { getExtraParam } = extraConfig || {}; let downloadProps; if (typeof data === 'string') { downloadProps = { url: data, }; } else if (isRequestConfig(data)) { const isDesign = isDesignMode(this.props); downloadProps = { service: { ...transRequestConfigToRemote({ requestConfig: { ...data, params: undefined }, isDesign, ...this.getCommonParams(), getExtraParam, }), formatResult: handleResultProcessFunc(data), formatParam: (param) => { return handleRequestParams(data?.params, { ...this.getCommonParams(), isDesign, getExtraParam, }); }, }, }; downloadProps.requestConfig = downloadProps.service; } return downloadProps; }; getCommonParams = () => { const { _context } = this.props; return { state: _context?.state, recordDataSource: this.getFilterParams(), urlParamsDataSource: this.getUrlParams(), isDesign: isDesignMode(this.props), }; }; calculateHover = (buttonHoverInfo, config) => { const { selectedRowKeys, selectedRowRecords } = config || {}; const needHover = buttonHoverInfo?.needHover; const hoverInfo = buttonHoverInfo?.hoverInfo; if (needHover && (hoverInfo?.title || hoverInfo?.content)) { const commonParams = this.getCommonParams(); const title = calculateTextExprValue(hoverInfo?.title, { ...commonParams, extraParamList: [selectedRowKeys, selectedRowRecords], }); const content = calculateTextExprValue(hoverInfo?.content, { ...commonParams, extraParamList: [selectedRowKeys, selectedRowRecords], }); if (title || content) { return { title, content, }; } } }; makeButton = (item, area, extraConfig) => { const { buttonProps } = extraConfig || {}; const isDesign = isDesignMode(this.props); const filterParams = this.getFilterParams(); const { _context, _dataSource } = this.props; const { iconType, primaryKey, optType, options = {}, children, disabled, hidden, buttonHoverInfo, ...rest } = item; const remoteOperation = this.getRemoteOperation(); const innerInfo = remoteOperation?.current?.innerInfo; let result = { ...rest, children, }; const action = getButtonAction({ ...item, position: area }); const getRenderDom = getItem(area, optType, 'getRenderDom'); const componentDefine = getRunTimeItem(optType); const isHidden = executeObjectExpr( hidden, { [__formValue__]: filterParams, [__filterValue__]: filterParams, [__dataSource__]: _context?.state, }, filterParams, _context?.state, ); let isDisabled; if (action && optType !== 'export' && optType !== 'ossImport') { } else { isDisabled = executeObjectExpr( disabled, { [__formValue__]: filterParams, [__filterValue__]: filterParams, [__dataSource__]: _context?.state, }, filterParams, _context?.state, _dataSource?.[__selectedRowKeys__] || [], _dataSource?.[__selectedRowRecords__] || [], ); } if (isHidden) { return null; } if (optType === 'download') { const { url } = options; return (selectedRowKeys, selectedRowRecords) => { let downloadProps; if (typeof url === 'function') { downloadProps = { url: executeFunction(url, filterParams, _context?.state), }; } else { downloadProps = this.getDownloadProps(url, { getExtraParam: () => { const { currentPage, pageSize } = innerInfo?.pageInfo || {}; return { currentPage, pageSize, }; }, }); } let tempDom = ( <CnDownload buttonText={children} buttonProps={{ ...buttonProps, type: item?.type, disabled: isDisabled, }} {...downloadProps} /> ); const { title, content } = this.calculateHover(buttonHoverInfo, { selectedRowKeys, selectedRowRecords, }) || {}; if (title || content) { const oldDom = ( <div style={{ display: 'inline-block' }}>{tempDom}</div> ); tempDom = ( <CnBalloon trigger={oldDom} title={title} closable={false}> {content} </CnBalloon> ); } return tempDom; }; } else if (optType === 'ossImport') { const { createService, pollingService, uploadService, templateUrl, hideLoop, dialogDescription, } = options; const pollingServiceResult = transRequestConfigToRemote({ requestConfig: pollingService, ...this.getCommonParams(), }); if ( pollingServiceResult && typeof pollingService?.resultProcessFunc === 'function' ) { pollingServiceResult.formatResult = handleResultProcessFunc(pollingService); } return (selectedRowKeys, selectedRowRecords) => { let tempDom; const extraProps = { autoImport: true, hideLoop, }; const uploadMsgSlot = []; let realDes = dialogDescription; if (typeof dialogDescription === 'function') { realDes = executeFunction( dialogDescription, this.getFilterParams(), _context?.state, selectedRowKeys, selectedRowRecords, ); } const downloadProps = this.getDownloadProps(templateUrl); if (downloadProps) { uploadMsgSlot.push( <Box direction='row' align='center'> {$i18n.get({ id: 'PleaseDownload', dm: '请下载' })}&nbsp; <CnDownload buttonProps={{ text: true, type: 'primary', disabled: isDisabled, }} buttonText={$i18n.get({ id: 'ImportFileTemplate', dm: '导入文件模板', })} {...downloadProps} /> </Box>, ); } if (realDes) { uploadMsgSlot.push( <Box direction='row' align='center'> {realDes} </Box>, ); } if (isArrayNotEmpty(uploadMsgSlot)) { extraProps.uploadMsgSlot = uploadMsgSlot; } tempDom = ( <CnOSSImport buttonProps={{ ...buttonProps, disabled: isDisabled, type: item?.type, }} {...extraProps} buttonText={children} onSuccess={(res) => { if (res?.status !== 'EXECUTING') { this.load(); } }} onSome={(res) => { this.load(); }} uploadProps={{ service: transRequestConfigToRemote({ requestConfig: uploadService, handleParams: () => { return { selectedRowKeys, selectedRowRecords, }; }, ...this.getCommonParams(), needFormatResult:true }), description: '', }} createService={(res) => { return makeRequest({ handleParams: () => { return { key: res, }; }, buttonConfig: { options: { requestConfig: createService, }, }, ...this.getCommonParams(), needSuccessToast: false, isDesign, }).then((res) => { return getRealResponse(res)?.data; }); }} pollingService={pollingServiceResult} pollingRequestConfig={pollingServiceResult} /> ); const { title, content } = this.calculateHover(buttonHoverInfo, { selectedRowKeys, selectedRowRecords, }) || {}; if (title || content) { const oldDom = ( <div style={{ display: 'inline-block' }}>{tempDom}</div> ); tempDom = ( <CnBalloon trigger={oldDom} title={title} closable={false}> {content} </CnBalloon> ); } return tempDom; }; } else if (optType === 'export') { const { createService, pollingService, hideLoop, needRename, defaultJobName, autoDownload, } = options; const extraProps = {}; if ( needRename === true && typeof defaultJobName === 'string' && defaultJobName.length > 0 ) { extraProps.renameDialogProps = { defaultJobName, }; } if (autoDownload === false) { extraProps.autoDownload = false; } const pollingServiceResult = transRequestConfigToRemote({ requestConfig: pollingService, ...this.getCommonParams(), noQsStringifyFormatting: true, }); if ( pollingServiceResult && typeof pollingService?.resultProcessFunc === 'function' ) { pollingServiceResult.formatResult = handleResultProcessFunc(pollingService); } return (selectedRowKeys, selectedRowRecords) => { const { title, content } = this.calculateHover(buttonHoverInfo, { selectedRowKeys, selectedRowRecords, }) || {}; let tempDom = ( <CnExport autoDownload {...extraProps} needRename={needRename} hideLoop={hideLoop} buttonText={children} buttonProps={{ ...buttonProps, disabled: isDisabled, type: item?.type, }} showAsyncDialog createService={(fileName) => { let jobName = fileName || {}; if (typeof fileName === 'string') { jobName = { jobName: fileName, }; } return makeRequest({ handleParams: () => { const filterParams = this.getFilterParams(); let temp = { selectedRowKeys, selectedRowRecords, ...jobName, }; if (isPlainObject(filterParams)) { temp = { ...filterParams, ...temp, }; } return temp; }, buttonConfig: { options: { requestConfig: createService, }, }, ...this.getCommonParams(), needSuccessToast: false, isDesign, }).then((res) => { return getRealResponse(res)?.data; }); }} pollingService={pollingServiceResult} /> ); if (title || content) { const oldDom = ( <div style={{ display: 'inline-block' }}>{tempDom}</div> ); tempDom = ( <CnBalloon trigger={oldDom} title={title} closable={false}> {content} </CnBalloon> ); } return tempDom; }; } else if (typeof getRenderDom === 'function') { result = (selectedRowKeys, selectedRowRecords) => { return getRenderDom({ ...item, state: _context?.state, position: area, selectedRowKeys, selectedRowRecords, tableRef: this, isDesign, makeButton: this.makeButton, buttonConfig: item, recordDataSource: filterParams, }); }; } if (action) { if (result.children && iconType && typeof iconType === 'string') { result.children = [ <span style={{ marginRight: '4px' }}>{renderIcon(iconType)}</span>, result.children, ]; } result.onClick = (e, selectedRowKeys, selectedRowRecords) => { action({ buttonConfig: item, _context, selectedRowKeys, selectedRowRecords, tableRef: this, componentProps: this.props, position: area, ...this.getCommonParams(), }); }; result.disabled = (selectedRowKeys, selectedRowRecords) => { // 单选初始是个空数组 选择了是个字符数字 // if(area === ButtonPosition.tableBatchArea && Array.isArray(selectedRowKeys) ? !(selectedRowKeys?.length > 0) : !selectedRowKeys) { // return true; // } return executeObjectExpr( disabled, { [__formValue__]: filterParams, [__filterValue__]: filterParams, [__dataSource__]: _context?.state, }, filterParams, _context?.state, selectedRowKeys || [], selectedRowRecords || [], ); }; let needHover; let hoverInfo; if (options?.needHover && options?.hoverInfo) { needHover = options?.needHover; hoverInfo = options?.hoverInfo; } else { needHover = buttonHoverInfo?.needHover; hoverInfo = buttonHoverInfo?.hoverInfo; } if (needHover && (hoverInfo?.title || hoverInfo?.content)) { const originalResult = { ...result }; result = (selectedRowKeys, selectedRowRecords) => { const commonParams = this.getCommonParams(); const title = calculateTextExprValue(hoverInfo?.title, { ...commonParams, extraParamList: [selectedRowKeys, selectedRowRecords], }); const content = calculateTextExprValue(hoverInfo?.content, { ...commonParams, extraParamList: [selectedRowKeys, selectedRowRecords], }); let tempDom = ( <CnButton {...originalResult} disabled={originalResult?.disabled?.(selectedRowKeys)} onClick={(e) => { originalResult?.onClick?.( e, selectedRowKeys, selectedRowRecords, ); }} /> ); if (title || content) { const oldDom = ( <div style={{ display: 'inline-block' }}>{tempDom}</div> ); tempDom = ( <CnBalloon trigger={oldDom} title={title} closable={false}> {content} </CnBalloon> ); } return tempDom; }; } return result; } else if (componentDefine?.component) { const component = getRealizeValue(componentDefine.component); if (component) { result = (selectedRowKeys, selectedRowRecords) => { const { title, content } = this.calculateHover(buttonHoverInfo, { selectedRowKeys, selectedRowRecords, }) || {}; let tempDom = React.createElement(component, { ...options, selectedRowKeys, selectedRowRecords, [_selectedRowKeys]: selectedRowKeys, [_selectedRowRecords]: selectedRowRecords, [_state]: _context?.state, buttonConfig: item, children, _context, [_bindFilterData]: this.getFilterParams(), [_getBindFilterData]: this.getFilterParams, tableRef: this, disabled: isDisabled, hidden: isHidden, [_getContext]: () => { return _context; }, }); if (title || content) { const oldDom = ( <div style={{ display: 'inline-block' }}>{tempDom}</div> ); tempDom = ( <CnBalloon trigger={oldDom} title={title} closable={false}> {content} </CnBalloon> ); } return tempDom; }; } return result; } return result; }; getFilterParams = () => { let filterParams = {}; const { _context, _bindFilterDataSourceName } = this.props; if (_context && _bindFilterDataSourceName) { filterParams = transProxyToObject( _context?.state?.[_bindFilterDataSourceName], ); } return filterParams; }; getUrlParams = () => { const { _context } = this.props; return _context?.state?.urlParams || {}; }; handleRowDetail = (rowDetail) => { if (typeof rowDetail?.renderDetail === 'string') { const componentDefine = getRunTimeItem(rowDetail.renderDetail); if (componentDefine?.component) { const component = getRealizeValue(componentDefine.component); if (component) { const { _context } = this.props; return { rowDetail: { renderDetail: (record, index) => { return React.createElement(component, { record, index, [_state]: _context?.state, [_tableRef]: this, _context, }); }, }, }; } } } return {}; }; handleSelectChange = (selectType, selectedRowKeys, selectedRowRecords) => { const { onChange, isFromFormItem } = this.props; let realSelectedRowKeys = selectedRowKeys; let realSelectedRowRecords = selectedRowRecords; if (selectType === 'single' && !isFromFormItem) { realSelectedRowKeys = [selectedRowKeys]; realSelectedRowRecords = [selectedRowRecords]; } this.setDataSource({ [__selectedRowKeys__]: realSelectedRowKeys || [], [__selectedRowRecords__]: realSelectedRowRecords || [], }); if (typeof onChange === 'function') { onChange(realSelectedRowKeys); } }; setDataSource = (data) => { const { _context, _dataSource, _dataSourceName } = this.props; setDataToDs({ _context, _dataSource, _dataSourceName, data, }); }; sendRequestFinishEvent = (newRes) => { const { _context } = this.props; emitEvent(CnTableRequestFinish, { [_getContext]: () => { return _context; }, [_tableRef]: this, [_getBindFilterData]: this.getFilterParams, [_tableResponse]: newRes, }); }; setTableInfo = (data) => { const remoteOperation = this.getRemoteOperation(); const newData = {}; if (isPlainObject(data)) { const { paging, tableData, extra, tableExtra } = data; const { totalCount } = data.paging || {}; if (typeof totalCount === 'number') { newData[__totalCount__] = totalCount; } if (isPlainObject(paging)) { newData[__paging__] = paging; } if (Array.isArray(tableData)) { newData[__tableData__] = tableData; } if (isPlainObject(tableExtra)) { newData[__tableExtra__] = tableExtra; } else if (isPlainObject(extra)) { newData[__tableExtra__] = extra; } else { newData[__tableExtra__] = {}; } const innerInfo = remoteOperation?.current?.innerInfo; if (innerInfo) { const { columns } = innerInfo; if (Array.isArray(columns)) { newData[__tableColumns__] = columns; if(columns.length === 0) { setTimeout(()=>{ const realColumns = remoteOperation?.current?.innerInfo?.columns; if(Array.isArray(realColumns) && realColumns.length > 0) { this.setDataSource({ __tableColumns__: realColumns, }); } }) } } } } if (Object.keys(newData).length > 0) { this.setDataSource(newData); } // if(isPlainObject(data?.paging)) { // const { _dataSourceName, _context } = this.props; // const oldTotalCount = _context?.state?.[_dataSourceName]?.[__totalCount__] // const { totalCount } = data.paging; // if(typeof totalCount === 'number' && totalCount !== oldTotalCount) { // this.setDataSource({ // [__totalCount__]: totalCount // }) // } // } }; makeTableSlot = (slot) => { if (isPlainObject(slot) && Object.keys(slot).length > 0) { const { _context, _dataSourceName } = this.props; const result = {}; for (const key in slot) { const temp = slot[key]; if (key?.includes('unsafe')) { } else if (typeof temp === 'function') { result[key] = ( selectedRowKeys, selectedRowRecords, dataSource, tableInfo, ) => { return executeFunction( temp, selectedRowKeys, selectedRowRecords, dataSource, tableInfo, _context?.state, ); }; } else if (typeof temp === 'string') { const componentDefine = getRunTimeItem(temp); if (componentDefine?.component) { const component = getRealizeValue(componentDefine.component); if (component) { const extraProps = slot[`${key}Options`]; result[key] = ( selectedRowKeys, selectedRowRecords, dataSource, tableInfo, ) => { return React.createElement(component, { selectedRowKeys, selectedRowRecords, dataSource, tableInfo, [_state]: _context?.state, [_getContext]: () => { return _context; }, [_getBindFilterData]: this.getFilterParams, [_getCurrentTableInfo]: () => { return _context?.state?.[_dataSourceName]; }, ...extraProps, }); }; } } } } if (Object.keys(result).length > 0) { return result; } } }; getFilterWaitComponentList = () => { let result; const { _context, _bindFilterDataSourceName } = this.props; if (isPlainObject(_context?._views) && _bindFilterDataSourceName) { for (const nodeId in _context?._views) { const tempView = _context?._views[nodeId]; if (tempView?._props?._dataSourceName === _bindFilterDataSourceName) { const tempResult = calculateWaitComponentList( tempView?._props?.config, tempView?._props?.defaultParams, ); result = tempResult?.waitComponentList; break; } } } return result; }; getTreeConfig = () => { const { tree } = this.props; const { openKeys } = this.state; if (tree === true && isArrayNotEmpty(openKeys)) { return { openKeys, onChangeOpenKeys: (list) => { this.setState({ openKeys: list, }); }, }; } }; makeRemote = (originRemote, extraConfig, originProps) => { const { manual, record, isInChildTable } = extraConfig || {}; const { _context, asciiSort, treeTableAsyncRequestConfig, primaryKey } = originProps; let remote; if (originRemote) { const realUrl = getRealRequestUrl({ requestConfig: originRemote, state: _context?.state, }); if (originRemote?.serviceType === 'tiangong') { const { guid } = originRemote || {}; remote = { // url: 'https://mocks.alibaba-inc.com/mock/conelowcode/queryData', url: 'https://cn-x-gateway.cainiao.test/cone/buc-for-l4/queryData', method: 'post', paramsTransform: (param) => { return { conditions: this.getFilterParams(), guid, ...param, }; }, instance: this.remoteInstance, requestOptions: { withCredentials: true, }, onError: (err) => { if (err?.errorCode === '001') { this.setState({ hasPermission: false, permissionTip: '您没有当前数据表的权限,请点此申请', }); } else if (err?.errorCode === '002') { this.setState({ hasPermission: false, permissionTip: '您已经提交权限申请,请点此查看审批进度', permissionLink: err?.errorMsg, }); } }, }; } else if (realUrl) { const { params = [], resultProcessFunc, serviceType, mockData, timeout, contentType, method, } = originRemote; remote = { ...originRemote, asciiSort, params: undefined, paramsTransform: (param) => { const { currentPage, pageSize, sortList } = param || {}; const filterParams = this.getFilterParams(); const realParams = handleRequestParams(params, { urlParamsDataSource: this.getUrlParams(), recordDataSource: filterParams, state: _context?.state, extraParam: { currentPage, pageSize, record, }, extraParamList: [ { currentPage, pageSize, record, sortList, }, ], flexibleParams: true,