Commit 7e486a8a authored by 陈龙's avatar 陈龙

fix: 修复文件引用错误

parent ab5be8e3
export const RESTART_ON_REMOUNT = '@@saga-injector/restart-on-remount';
export const DAEMON = '@@saga-injector/daemon';
export const ONCE_TILL_UNMOUNT = '@@saga-injector/once-till-unmount';
export const FILTER_FOLER_REG =
/(configs|configuration|framework|iframe|Product|product|productex|project|qrcode|threedimensional|video|widgetconfigs)/;
export const FILTER_FOLER_WEB5 = /(pages)/;
export const SERVICE_APP_GET_UI_META = 'app.getUIMeta';
export const SERVICE_APP_LOGIN_MODE = {
password: 'password',
dingding: 'dingding',
weixin: 'weixin',
phone: 'phone',
};
export const LOGIN_DISPLAY = {
Account: 'Account',
WeChart: 'WeChart',
Mobile: 'Mobile',
};
export const LOGIN_WAY = {
Account: 'pdw',
WeChart: 'iotWechat',
Mobile: 'iotPhone',
};
export const WX_REDIRECT_URI = 'https://panda-water.com/civbase/user/login';
export const SERVICE_INTERFACE_SUCCESS_CODE = 0;
export const SERVICE_INTERFACE_PARAMS_EXCEPTION_CODE = -1; // 服务参数异常
export const SERVICE_INTERFACE_HANDLE_EXCEPTION_CODE = -2; // 服务处理异常
export const SERVICE_APP_CLOSE_ALL_TABS = 'app.close.tabs';
export const REQUEST_HTTP = 'http';
export const REQUEST_POP = 'pop';
export const REQUEST_METHOD_GET = 'get';
export const REQUEST_METHOD_POST = 'post';
export const REQUEST_METHOD_PUT = 'put';
export const REQUEST_METHOD_DELETE = 'delete';
export const RESPONSE_TYPE = 'blob';
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围) ** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
**/ **/
import { request } from '@wisdom-utils/utils'; import { request } from '@wisdom-utils/utils';
import * as constants from '../../constants'; import * as constants from '../constants';
const BASEURL = '/PandaAssets/Assets/ReportManager'; const BASEURL = '/PandaAssets/Assets/ReportManager';
export const API = { export const API = {
...@@ -97,12 +97,13 @@ const reportService = { ...@@ -97,12 +97,13 @@ const reportService = {
type: constants.REQUEST_METHOD_POST, type: constants.REQUEST_METHOD_POST,
}, },
}; };
export const submitReportData = (params, data) => request({ export const submitReportData = (params, data) =>
request({
url: API.UPDATE_REPORT_DATA, url: API.UPDATE_REPORT_DATA,
method: 'post', method: 'post',
params, params,
data, data,
}); });
export const exportAccountData = (options, params, data) => export const exportAccountData = (options, params, data) =>
request({ request({
url: API.EXPORT_ACCOUNT_DATA, url: API.EXPORT_ACCOUNT_DATA,
...@@ -111,9 +112,10 @@ export const exportAccountData = (options, params, data) => ...@@ -111,9 +112,10 @@ export const exportAccountData = (options, params, data) =>
params, params,
data, data,
}); });
export const addReportDetailInfoIndex = (data) => request({ export const addReportDetailInfoIndex = (data) =>
request({
url: API.ADD_REPORT_DETAIL_INFO_INDEX, url: API.ADD_REPORT_DETAIL_INFO_INDEX,
method: 'post', method: 'post',
data, data,
}); });
export default reportService; export default reportService;
/** /**
* 时间组选择:支持 全部,日,月,年,自定义 类型 * 时间组选择:支持 全部,日,月,年,自定义 类型 props:
* props:
* onChange: ({dateFrom, dateTo}, model) => {}。切换时间类型或时间会触发onChange,并传递选择的时间范围和类型。 * onChange: ({dateFrom, dateTo}, model) => {}。切换时间类型或时间会触发onChange,并传递选择的时间范围和类型。
* 注:dateFrom和dateTo都是格式化后的字符串 * 注:dateFrom和dateTo都是格式化后的字符串
* format: 格式化字符串格式,默认"YYYY-MM-DD HH:mm:ss",参看moment格式化支持的 * format: 格式化字符串格式,默认"YYYY-MM-DD HH:mm:ss",参看moment格式化支持的
...@@ -38,7 +37,7 @@ const dateForModel = (model, date = moment()) => { ...@@ -38,7 +37,7 @@ const dateForModel = (model, date = moment()) => {
} }
return result; return result;
}; };
const textForModel = model => { const textForModel = (model) => {
switch (model) { switch (model) {
case 'day': case 'day':
return '日'; return '日';
...@@ -91,7 +90,7 @@ const DatePickerGroup = ({ ...@@ -91,7 +90,7 @@ const DatePickerGroup = ({
}, [value, dateModel]); }, [value, dateModel]);
// 切换类型 // 切换类型
const changeModel = e => { const changeModel = (e) => {
const _model = e.target.value; const _model = e.target.value;
const _dateValue = dateForModel(_model); const _dateValue = dateForModel(_model);
if (!value && !dateModel) { if (!value && !dateModel) {
...@@ -168,7 +167,10 @@ const DatePickerGroup = ({ ...@@ -168,7 +167,10 @@ const DatePickerGroup = ({
break; break;
case 'custom': case 'custom':
_result = ( _result = (
<DatePicker.RangePicker onChange={changeRangeDate} value={[dateValue.dateFrom, dateValue.dateTo]} /> <DatePicker.RangePicker
onChange={changeRangeDate}
value={[dateValue.dateFrom, dateValue.dateTo]}
/>
); );
break; break;
case 'all': case 'all':
...@@ -182,7 +184,7 @@ const DatePickerGroup = ({ ...@@ -182,7 +184,7 @@ const DatePickerGroup = ({
return ( return (
<Space size={8}> <Space size={8}>
<Radio.Group value={model} onChange={changeModel} style={{ whiteSpace: 'nowrap' }}> <Radio.Group value={model} onChange={changeModel} style={{ whiteSpace: 'nowrap' }}>
{showModels.map(item => ( {showModels.map((item) => (
<Radio.Button value={item} key={item}> <Radio.Button value={item} key={item}>
{textForModel(item)} {textForModel(item)}
</Radio.Button> </Radio.Button>
......
...@@ -7,6 +7,6 @@ const extraComponents = { ...@@ -7,6 +7,6 @@ const extraComponents = {
returnImage: (data) => { returnImage: (data) => {
return <img width={200} height={200} src={pic} alt={data.alt} />; return <img width={200} height={200} src={pic} alt={data.alt} />;
}, },
default: () => <span>若需要使用弹窗功能,请开发或配置功能函数</span> default: () => <span>若需要使用弹窗功能,请开发或配置功能函数</span>,
}; };
export default extraComponents; export default extraComponents;
/** /**
** 轻量化报表通用配置页面 * * 轻量化报表通用配置页面 * create by ChenLong on 2022/6/22 *
** create by ChenLong on 2022/6/22 * 功能路径:src\pages\product\ReportsManage\ReportsManage.js * 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
** 功能路径:src\pages\product\ReportsManage\ReportsManage.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
* @Changelog:
* editComponentVisible && detailsComponentVisible 共同作用组件的显示
* *
**/ * @changelog:
* editComponentVisible && detailsComponentVisible 共同作用组件的显示
*/
/** /**
* @Description: 功能描述:参考台账概念,重新定义 * @description: 功能描述:参考台账概念,重新定义
* @Tips: 1. 如果需要对字段进行处理,增加功能之类的。需要提前确定返回值的类型. * @tips: 1. 如果需要对字段进行处理,增加功能之类的。需要提前确定返回值的类型.
* 2. 如果要用customerState来控制页面按钮等,需要按照给定的权限值进行配置 * 2. 如果要用customerState来控制页面按钮等,需要按照给定的权限值进行配置
* @Params: <ReportManage params={{reportName,pageSize,filterFields,filterValues,state,customerState}}> * @params: <ReportManage
* params={{reportName,pageSize,filterFields,filterValues,state,customerState}}>
*
* reportName: 报表名称; * reportName: 报表名称;
* pageSize: 按需配置,默认加载100; * pageSize: 按需配置,默认加载100;
* filterFields: 需要默认加载的过滤条件的field,英文逗号分割,与filterValues一一对应; * filterFields:
* filterValues: 需要默认加载的过滤条件的value,英文逗号分割,与filterFields一一对应; * 需要默认加载的过滤条件的field,英文逗号分割,与filterValues一一对应;
* filterValues:
* 需要默认加载的过滤条件的value,英文逗号分割,与filterFields一一对应;
* state: delete|edit|scan 各种权限; * state: delete|edit|scan 各种权限;
*
* customerState: ['filters','sortBtn','exportBtn','editBtn','deleteBtn','pagination']; * customerState: ['filters','sortBtn','exportBtn','editBtn','deleteBtn','pagination'];
*
* sortFields: '排序字段1,排序字段2,排序字段3' * sortFields: '排序字段1,排序字段2,排序字段3'
* @Config: * @config:
* 【数值】 [prefix]_d%|0.00|_d%[suffix]|金额 = 前缀|精度|后缀|金额类的数据(千分位),可分别设置。 * 【数值】 [prefix]_d%|0.00|_d%[suffix]|金额 = 前缀|精度|后缀|金额类的数据(千分位),可分别设置。
* 【标签】 split=, 分隔符。 * 【标签】 split=, 分隔符。
*
* 【功能】 功能配置框内,配置需要跳转功能所需参数,type、url是必须功能,需要type判断类型,需要通过url去解析加载组件。 * 【功能】 功能配置框内,配置需要跳转功能所需参数,type、url是必须功能,需要type判断类型,需要通过url去解析加载组件。
* @Type: * @type:
* 【文本】普通文本 * 【文本】普通文本
* 【数值】数值类型的文本 * 【数值】数值类型的文本
* 【标签】文本渲染成标签,具有不同颜色; * 【标签】文本渲染成标签,具有不同颜色;
* 【功能】“功能”会在当前页内去展示,会卸载掉列表页,加载功能组件。配置 type + url + 自定义字段 的配置项,自行解析加载即可; * 【功能】“功能”会在当前页内去展示,会卸载掉列表页,加载功能组件。配置 type +
* url + 自定义字段 的配置项,自行解析加载即可;
* -------------------- 待需求提出后开发 ----------------- * -------------------- 待需求提出后开发 -----------------
*
* 【链接】内链外链,点击可跳转;配置规则:配置链接即可; * 【链接】内链外链,点击可跳转;配置规则:配置链接即可;
* 【弹窗】modal弹窗弹出,弹窗内的具体业务自行配置;配置规则:[function_name];[...params]; * 【弹窗】modal弹窗弹出,弹窗内的具体业务自行配置;配置规则:[function_name];[...params];
*
* ------------------------------------------------------ * ------------------------------------------------------
* @Table: * @table:
* 表头:表头需要支持多级表头、合并; * 表头:表头需要支持多级表头、合并;
* 列:列支持设置筛选; * 列:列支持设置筛选;
* 固定行、固定列:可根据配置生成固定行、列; * 固定行、固定列:可根据配置生成固定行、列;
* @Control: * @control:
* 固定筛选:拥有固定筛选框,根据配置显示可搜索字段; * 固定筛选:拥有固定筛选框,根据配置显示可搜索字段;
*
* 可配置筛选框:根据字段配置,将字段设置成筛选条件,枚举出该字段所有值,提供用户进行选择,然后进行筛选;筛选框具体形态可根据配置字段来渲染; * 可配置筛选框:根据字段配置,将字段设置成筛选条件,枚举出该字段所有值,提供用户进行选择,然后进行筛选;筛选框具体形态可根据配置字段来渲染;
* 导出功能:各类导出功能按钮; * 导出功能:各类导出功能按钮;
*
* 时间筛选框:单表唯一;需要变更,支持多时间参数的筛选 * 时间筛选框:单表唯一;需要变更,支持多时间参数的筛选
* @State: 参考台账权限 * @state: 参考台账权限 delete 全部权限
* delete 全部权限
* edit 除删除外的权限 * edit 除删除外的权限
* scan 查看权限 * scan 查看权限
* */ */
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import { Row, Button, Tag, message, Form, Space, Modal, Select, Table, Dropdown, Menu, Spin } from 'antd';
import { import {
SortAscendingOutlined, MinusCircleOutlined, ExportOutlined, FormOutlined, Row,
Button,
Tag,
message,
Form,
Space,
Modal,
Select,
Table,
Dropdown,
Menu,
Spin,
} from 'antd';
import {
SortAscendingOutlined,
MinusCircleOutlined,
ExportOutlined,
FormOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import BasicTable from '@wisdom-components/basictable'; import BasicTable from '@wisdom-components/basictable';
import ReturnControlComponent from './components/Control'; import ReturnControlComponent from './components/Control';
import { reportService } from './api/index'; import { reportService } from './api/index';
import style from './index.less'; import style from './index.less';
import { exportAccountData } from './api/service/report'; import { exportAccountData } from './api/service/report';
import extraComponents from './extra/extraComponents';
import DatePickerGroup from './components/DatePickerGroup'; import DatePickerGroup from './components/DatePickerGroup';
import moment from 'moment'; import moment from 'moment';
import DetailsComponent from './extra/detailsComponent'; import DetailsComponent from './extra/detailsComponent';
...@@ -68,7 +92,9 @@ import { ...@@ -68,7 +92,9 @@ import {
handleWidget, handleWidget,
handleModal, handleModal,
handleDateString, handleDateString,
handleDateTimeString, handlePageSize, handleSortFields, handleDateTimeString,
handlePageSize,
handleSortFields,
} from './utils/handlers'; } from './utils/handlers';
import { hasMoney, isArray, isNumber, isString, returnHandledNumber } from './utils/utils'; import { hasMoney, isArray, isNumber, isString, returnHandledNumber } from './utils/utils';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
...@@ -99,19 +125,19 @@ const PERMISSION = { ...@@ -99,19 +125,19 @@ const PERMISSION = {
// 操作列 // 操作列
'editBtn', 'editBtn',
], ],
scan: [ scan: ['filters', 'pagination'],
'filters',
'pagination',
],
}; };
const BasicReport = (props) => { const BasicReport = (props) => {
const { reportName, pageSize, filterFields, filterValues, state, customerState, sortFields } = props.params; const { reportName, pageSize, filterFields, filterValues, state, customerState, sortFields } =
const permission = customerState && isArray(customerState) ? customerState : PERMISSION[(state || 'delete')]; props.params;
const permission =
customerState && isArray(customerState) ? customerState : PERMISSION[state || 'delete'];
const tableWrapperRef = useRef(); const tableWrapperRef = useRef();
const controlRef = useRef(); const controlRef = useRef();
if (!reportName) return <div className={style.lackParams}> if (!reportName)
未配置reportName,请完善配置并重新登陆后查看页面! return (
</div>; <div className={style.lackParams}>未配置reportName,请完善配置并重新登陆后查看页面!</div>
);
const [tableStruct, setTableStruct] = useState([]); // 临时使用,看后续是否需要保留 const [tableStruct, setTableStruct] = useState([]); // 临时使用,看后续是否需要保留
const [columns, setColumns] = useState([]); // 表头设置 const [columns, setColumns] = useState([]); // 表头设置
const [tableData, setTableData] = useState([]); // 表数据 const [tableData, setTableData] = useState([]); // 表数据
...@@ -119,7 +145,9 @@ const BasicReport = (props) => { ...@@ -119,7 +145,9 @@ const BasicReport = (props) => {
current: 1, current: 1,
total: 0, total: 0,
pageSize: handlePageSize(pageSize) || 100, pageSize: handlePageSize(pageSize) || 100,
pageSizeOptions: [...new Set([20, 50, 100].concat(handlePageSize(pageSize)))].filter(item => Number(item)).sort((a, b) => Number(a) - Number(b)), pageSizeOptions: [...new Set([20, 50, 100].concat(handlePageSize(pageSize)))]
.filter((item) => Number(item))
.sort((a, b) => Number(a) - Number(b)),
showQuickJumper: true, showQuickJumper: true,
showSizeChanger: true, showSizeChanger: true,
onShowSizeChange: (current, size) => { onShowSizeChange: (current, size) => {
...@@ -143,11 +171,13 @@ const BasicReport = (props) => { ...@@ -143,11 +171,13 @@ const BasicReport = (props) => {
const [filterObject, setFilterObject] = useState({}); // 存控制条中,选了筛选条件的值 const [filterObject, setFilterObject] = useState({}); // 存控制条中,选了筛选条件的值
const [modalVisible, setModalVisible] = useState(false); const [modalVisible, setModalVisible] = useState(false);
const [allSortFields, setAllSortFields] = useState([]); // 设置所有列表 const [allSortFields, setAllSortFields] = useState([]); // 设置所有列表
const [selectedSortFields, setSelectedSortFields] = useState([{ const [selectedSortFields, setSelectedSortFields] = useState([
{
label: '主要排序', label: '主要排序',
value: '', value: '',
sort: 'asc', sort: 'asc',
}]); },
]);
const [summaryArray, setSummaryArray] = useState([]); // 总结栏,包括小计、总计 const [summaryArray, setSummaryArray] = useState([]); // 总结栏,包括小计、总计
const [tableY, setTableY] = useState(500); const [tableY, setTableY] = useState(500);
const [tableX, setTableX] = useState(1820); const [tableX, setTableX] = useState(1820);
...@@ -160,16 +190,8 @@ const BasicReport = (props) => { ...@@ -160,16 +190,8 @@ const BasicReport = (props) => {
const [tableLoading, setTableLoading] = useState(false); const [tableLoading, setTableLoading] = useState(false);
const [mergeObject, setMergeObject] = useState({}); const [mergeObject, setMergeObject] = useState({});
// const // const
const [timeFrom, setTimeFrom] = useState( const [timeFrom, setTimeFrom] = useState(moment().startOf(initDateModel).format(dateFormat));
moment() const [timeTo, setTimeTo] = useState(moment().endOf(initDateModel).format(dateFormat));
.startOf(initDateModel)
.format(dateFormat),
);
const [timeTo, setTimeTo] = useState(
moment()
.endOf(initDateModel)
.format(dateFormat),
);
const [extra, setExtra] = useState(<></>); const [extra, setExtra] = useState(<></>);
const [sortModalVisible, setSortModalVisible] = useState(false); const [sortModalVisible, setSortModalVisible] = useState(false);
const [currentReportId, setCurrentReportId] = useState(null); const [currentReportId, setCurrentReportId] = useState(null);
...@@ -191,9 +213,9 @@ const BasicReport = (props) => { ...@@ -191,9 +213,9 @@ const BasicReport = (props) => {
{ {
label: ( label: (
<Button <Button
size='middle' size="middle"
loading={exportLoading} loading={exportLoading}
type='text' type="text"
onClick={() => exportModule('pdf', 'pdf')} onClick={() => exportModule('pdf', 'pdf')}
icon={<ExportOutlined />} icon={<ExportOutlined />}
> >
...@@ -205,9 +227,9 @@ const BasicReport = (props) => { ...@@ -205,9 +227,9 @@ const BasicReport = (props) => {
{ {
label: ( label: (
<Button <Button
size='middle' size="middle"
loading={exportLoading} loading={exportLoading}
type='text' type="text"
onClick={() => exportModule('excel', 'xls')} onClick={() => exportModule('excel', 'xls')}
icon={<ExportOutlined />} icon={<ExportOutlined />}
> >
...@@ -221,7 +243,10 @@ const BasicReport = (props) => { ...@@ -221,7 +243,10 @@ const BasicReport = (props) => {
}; };
const exportModule = (type, extension) => { const exportModule = (type, extension) => {
setExportLoading(true); setExportLoading(true);
exportAccountData({ responseType: 'blob' }, { exportType: type }, { exportAccountData(
{ responseType: 'blob' },
{ exportType: type },
{
reportName, reportName,
pageIndex: 0, pageIndex: 0,
pageSize: 0, pageSize: 0,
...@@ -233,8 +258,9 @@ const BasicReport = (props) => { ...@@ -233,8 +258,9 @@ const BasicReport = (props) => {
fieldValue: '', fieldValue: '',
}, },
], ],
}) },
.then(res => { )
.then((res) => {
if (res && res.code === -1) return message.error(res.msg); if (res && res.code === -1) return message.error(res.msg);
const url = window.URL.createObjectURL( const url = window.URL.createObjectURL(
new Blob([res], { type: 'application/octet-stream;charset=UTF-8' }), new Blob([res], { type: 'application/octet-stream;charset=UTF-8' }),
...@@ -242,12 +268,13 @@ const BasicReport = (props) => { ...@@ -242,12 +268,13 @@ const BasicReport = (props) => {
const a = document.createElement('a'); const a = document.createElement('a');
a.href = url; a.href = url;
a.target = '_blank'; a.target = '_blank';
a.download = `${reportName}${moment().format('YYYY-MM-DD-HH-mm-ss').replaceAll('-', '')}.` + extension; a.download =
`${reportName}${moment().format('YYYY-MM-DD-HH-mm-ss').replaceAll('-', '')}.` + extension;
a.click(); a.click();
a.remove(); a.remove();
setExportLoading(false); setExportLoading(false);
}) })
.catch(err => { .catch((err) => {
setExportLoading(false); setExportLoading(false);
}); });
}; };
...@@ -272,16 +299,20 @@ const BasicReport = (props) => { ...@@ -272,16 +299,20 @@ const BasicReport = (props) => {
// 搜索框是否有值 // 搜索框是否有值
if (searchContent) _data.content = searchContent; if (searchContent) _data.content = searchContent;
// filterObject是存起来的控制栏的过滤条件 // filterObject是存起来的控制栏的过滤条件
let _filters = Object.keys(filterObject).filter(key => { let _filters = Object.keys(filterObject)
.filter((key) => {
let _value = filterObject[key]; let _value = filterObject[key];
return (isString(_value) && _value) || (isArray(_value) && _value.length); return (isString(_value) && _value) || (isArray(_value) && _value.length);
}).map(key => { })
.map((key) => {
let _value = filterObject[key]; let _value = filterObject[key];
if (isString(_value) && _value) return { if (isString(_value) && _value)
return {
fieldAlias: key, fieldAlias: key,
fieldValue: _value, fieldValue: _value,
}; };
if (isArray(_value) && _value.length) return { if (isArray(_value) && _value.length)
return {
fieldAlias: key, fieldAlias: key,
fieldValue: _value.join(','), fieldValue: _value.join(','),
}; };
...@@ -330,20 +361,16 @@ const BasicReport = (props) => { ...@@ -330,20 +361,16 @@ const BasicReport = (props) => {
}); });
setSelectedSortFields(_sortStringArray); setSelectedSortFields(_sortStringArray);
}; };
/** /** @description: 根据是否向下合并处理数据,返回合并的key的数组 */
* @Description: 根据是否向下合并处理数据,返回合并的key的数组
* */
const returnMergeArray = (config) => { const returnMergeArray = (config) => {
return config.filter(item => item.isMerge).map(item => item.fieldAlias); return config.filter((item) => item.isMerge).map((item) => item.fieldAlias);
}; };
/** /** @description: 根据配置和数据,计算出该合并的字段和每一行是否合并 */
* @Description: 根据配置和数据,计算出该合并的字段和每一行是否合并
* */
const handleDataToGetRowSpanArray = (config, data) => { const handleDataToGetRowSpanArray = (config, data) => {
let _arr = returnMergeArray(config); let _arr = returnMergeArray(config);
let _merge = {}; let _merge = {};
// _merge:{爱好:[[0,3],[3,5]]} // _merge:{爱好:[[0,3],[3,5]]}
_arr.forEach(key => { _arr.forEach((key) => {
_merge[key] = {}; _merge[key] = {};
let _currentIndex = 0; let _currentIndex = 0;
data.forEach((item, index) => { data.forEach((item, index) => {
...@@ -372,7 +399,9 @@ const BasicReport = (props) => { ...@@ -372,7 +399,9 @@ const BasicReport = (props) => {
pageSize: pageSize, pageSize: pageSize,
}); });
// sortFields // sortFields
reportService.getReportInfo(_data).then(res => { reportService
.getReportInfo(_data)
.then((res) => {
if (res.code === 0) { if (res.code === 0) {
let _reportDetails = res.data.reportDetails; let _reportDetails = res.data.reportDetails;
let _statisticalValues = res.data.statisticalValues; let _statisticalValues = res.data.statisticalValues;
...@@ -406,20 +435,21 @@ const BasicReport = (props) => { ...@@ -406,20 +435,21 @@ const BasicReport = (props) => {
setTableData([]); setTableData([]);
} }
setTableLoading(false); setTableLoading(false);
}).catch(err => { })
.catch((err) => {
console.log(err); console.log(err);
setTableLoading(false); setTableLoading(false);
}); });
}; };
/** /** @description: 在配置项中,isFilter: true 用来渲染控制框;filterRule: 下拉/文本/多选 */
* @Description: 在配置项中,isFilter: true 用来渲染控制框;filterRule: 下拉/文本/多选
* */
const getControlsBarConfig = (config) => { const getControlsBarConfig = (config) => {
let _data = config.filter(item => item.isFilter); let _data = config.filter((item) => item.isFilter);
let _searchPlaceholder = []; let _searchPlaceholder = [];
_data.filter(item => item.filterRule === '文本').forEach(item => _searchPlaceholder.push(item.fieldAlias)); _data
.filter((item) => item.filterRule === '文本')
.forEach((item) => _searchPlaceholder.push(item.fieldAlias));
setSearchPlaceholder(_searchPlaceholder); setSearchPlaceholder(_searchPlaceholder);
let _controls = _data.filter(item => ControlsType.includes(item.filterRule)); let _controls = _data.filter((item) => ControlsType.includes(item.filterRule));
setControls(_controls); setControls(_controls);
handleDate(_controls); handleDate(_controls);
}; };
...@@ -438,7 +468,9 @@ const BasicReport = (props) => { ...@@ -438,7 +468,9 @@ const BasicReport = (props) => {
// 合并列 // 合并列
let _colSpan = -1; let _colSpan = -1;
let _index = 0; let _index = 0;
config.filter(item => item.isShow).forEach((item, index) => { config
.filter((item) => item.isShow)
.forEach((item, index) => {
if (item.isStatistics) { if (item.isStatistics) {
_index += 1; _index += 1;
_colSpan = -1; _colSpan = -1;
...@@ -463,7 +495,7 @@ const BasicReport = (props) => { ...@@ -463,7 +495,7 @@ const BasicReport = (props) => {
}; };
} }
}); });
summary.forEach(item => { summary.forEach((item) => {
switch (item.totalType) { switch (item.totalType) {
case '全部': case '全部':
setHasTotal(true); setHasTotal(true);
...@@ -480,7 +512,8 @@ const BasicReport = (props) => { ...@@ -480,7 +512,8 @@ const BasicReport = (props) => {
}); });
// 增加操作列,总结栏最后一个单元格需要延伸一格 // 增加操作列,总结栏最后一个单元格需要延伸一格
let _sumArr = Object.values(_summaryConfig); let _sumArr = Object.values(_summaryConfig);
if (_sumArr && _sumArr.length) _sumArr = _sumArr.map((item, index) => { if (_sumArr && _sumArr.length)
_sumArr = _sumArr.map((item, index) => {
let _item = { ...item }; let _item = { ...item };
if (index === _sumArr.length - 1) _item.colSpan += 1; if (index === _sumArr.length - 1) _item.colSpan += 1;
return _item; return _item;
...@@ -508,7 +541,7 @@ const BasicReport = (props) => { ...@@ -508,7 +541,7 @@ const BasicReport = (props) => {
return _map[type] || _map['文本']; return _map[type] || _map['文本'];
}; };
const returnSortFields = (data) => { const returnSortFields = (data) => {
return data.map(item => item.fieldAlias); return data.map((item) => item.fieldAlias);
}; };
// 处理表格数据,生成表头 // 处理表格数据,生成表头
const returnColumn = (config, data) => { const returnColumn = (config, data) => {
...@@ -516,7 +549,7 @@ const BasicReport = (props) => { ...@@ -516,7 +549,7 @@ const BasicReport = (props) => {
//1. 合并表头; //1. 合并表头;
//2. 四类形态的渲染处理; //2. 四类形态的渲染处理;
//3. 多列表头排序;剔除掉原有图标,需要自己实现排序的按钮 //3. 多列表头排序;剔除掉原有图标,需要自己实现排序的按钮
let _config = [...config].filter(item => item.isShow); let _config = [...config].filter((item) => item.isShow);
function dataStruct(keyArray, dataIndex, obj, dataObj) { function dataStruct(keyArray, dataIndex, obj, dataObj) {
if (dataIndex < keyArray.length - 1) { if (dataIndex < keyArray.length - 1) {
...@@ -532,7 +565,7 @@ const BasicReport = (props) => { ...@@ -532,7 +565,7 @@ const BasicReport = (props) => {
let _tempObj = {}; let _tempObj = {};
let _fieldAliasArray = handleDataToGetRowSpanArray(_config, data); // 需要向下合并的字段 let _fieldAliasArray = handleDataToGetRowSpanArray(_config, data); // 需要向下合并的字段
_config.forEach(item => { _config.forEach((item) => {
let _item = { let _item = {
title: item.fieldAlias, title: item.fieldAlias,
dataIndex: item.fieldAlias, dataIndex: item.fieldAlias,
...@@ -610,14 +643,19 @@ const BasicReport = (props) => { ...@@ -610,14 +643,19 @@ const BasicReport = (props) => {
width: 60, width: 60,
fixed: 'right', fixed: 'right',
render: (text, record) => { render: (text, record) => {
return <Space className={style.handleColumnWrapper}> return (
{ <Space className={style.handleColumnWrapper}>
permission.includes('editBtn') ? {permission.includes('editBtn') ? (
<FormOutlined className={style.editButton} onClick={() => { <FormOutlined
className={style.editButton}
onClick={() => {
setEditComponentVisible(true); setEditComponentVisible(true);
setCurrentData(record); setCurrentData(record);
}} /> : '' }}
} />
) : (
''
)}
{/* { {/* {
permission.includes('deleteBtn') ? permission.includes('deleteBtn') ?
<DeleteOutlined disabled className={style.deleteButton} onClick={() => { <DeleteOutlined disabled className={style.deleteButton} onClick={() => {
...@@ -627,13 +665,14 @@ const BasicReport = (props) => { ...@@ -627,13 +665,14 @@ const BasicReport = (props) => {
}); });
}} /> : '' }} /> : ''
}*/} }*/}
</Space>; </Space>
);
}, },
}); });
} }
// 统计宽度 // 统计宽度
let _x = _tempArray.reduce((final, curr) => { let _x = _tempArray.reduce((final, curr) => {
return final += curr.width; return (final += curr.width);
}, 0); }, 0);
setTableX(_x); setTableX(_x);
return _tempArray; return _tempArray;
...@@ -665,24 +704,30 @@ const BasicReport = (props) => { ...@@ -665,24 +704,30 @@ const BasicReport = (props) => {
const paginationHeight = 75; // 分页部分的高度 const paginationHeight = 75; // 分页部分的高度
const tableHeaderHeight = tableHeaderLevel * 40; // 表头高度 const tableHeaderHeight = tableHeaderLevel * 40; // 表头高度
const summaryHeight = summaryArray.length ? 40 * (Number(hasTotal) + Number(hasSinglePage)) : 0; // 总结栏的高度 const summaryHeight = summaryArray.length ? 40 * (Number(hasTotal) + Number(hasSinglePage)) : 0; // 总结栏的高度
const _minus = clientHeight - _height - 16 - 4 - tableHeaderHeight - paginationHeight - summaryHeight - 10; const _minus =
clientHeight - _height - 16 - 4 - tableHeaderHeight - paginationHeight - summaryHeight - 10;
setListHeight(clientHeight - _height - paginationHeight - 4 - 6 - 16 - 2); setListHeight(clientHeight - _height - paginationHeight - 4 - 6 - 16 - 2);
setTableY(_minus); setTableY(_minus);
}; };
const getTableLevel = (config) => { const getTableLevel = (config) => {
let _level = config.reduce((final, curr) => { let _level =
return final = curr.level > final ? curr.level : final; config.reduce((final, curr) => {
return (final = curr.level > final ? curr.level : final);
}, 1) || 1; }, 1) || 1;
setTableHeaderLevel(_level); setTableHeaderLevel(_level);
}; };
const saveReportListSortFields = (callback) => { const saveReportListSortFields = (callback) => {
reportService.saveReportListSortFields({ reportService
.saveReportListSortFields({
reportId: currentReportId, reportId: currentReportId,
sortFields: selectedSortFields.filter(item => item.value).map(item => ({ sortFields: selectedSortFields
.filter((item) => item.value)
.map((item) => ({
fieldAlias: item.value, fieldAlias: item.value,
sortType: item.sort, sortType: item.sort,
})), })),
}).then(res => { })
.then((res) => {
if (res.code === 0) { if (res.code === 0) {
message.success('排序保存成功!'); message.success('排序保存成功!');
callback(); callback();
...@@ -691,14 +736,15 @@ const BasicReport = (props) => { ...@@ -691,14 +736,15 @@ const BasicReport = (props) => {
} }
}); });
}; };
/** /** @description: 判断是否存在【时间】类型的选择,并返回组件 */
* @Description: 判断是否存在【时间】类型的选择,并返回组件
* */
const handleDate = (obj) => { const handleDate = (obj) => {
let _typeObj = obj.find(item => item.filterRule === '日期'); let _typeObj = obj.find((item) => item.filterRule === '日期');
setHasDatePicker(_typeObj ? _typeObj.fieldAlias : ''); setHasDatePicker(_typeObj ? _typeObj.fieldAlias : '');
const _configItems = _typeObj.configItems.split('|'); const _configItems = _typeObj.configItems.split('|');
let _defaultDate = _configItems.find(item => item.includes('defaultDate='))?.replace('defaultDate=', '')?.split(','); let _defaultDate = _configItems
.find((item) => item.includes('defaultDate='))
?.replace('defaultDate=', '')
?.split(',');
if (_defaultDate && _defaultDate.length > 1) { if (_defaultDate && _defaultDate.length > 1) {
_defaultDate = { dateFrom: moment(_defaultDate[0]), dateTo: moment(_defaultDate[1]) }; _defaultDate = { dateFrom: moment(_defaultDate[0]), dateTo: moment(_defaultDate[1]) };
} else if (_defaultDate && _defaultDate.length === 1) { } else if (_defaultDate && _defaultDate.length === 1) {
...@@ -708,7 +754,9 @@ const BasicReport = (props) => { ...@@ -708,7 +754,9 @@ const BasicReport = (props) => {
} }
setDefaultDateConfig({ setDefaultDateConfig({
defaultDate: _defaultDate?.dateFrom, defaultDate: _defaultDate?.dateFrom,
defaultModel: _configItems.find(item => item.includes('defaultModel='))?.replace('defaultModel=', '') || 'year', defaultModel:
_configItems.find((item) => item.includes('defaultModel='))?.replace('defaultModel=', '') ||
'year',
}); });
}; };
useEffect(() => { useEffect(() => {
...@@ -732,142 +780,230 @@ const BasicReport = (props) => { ...@@ -732,142 +780,230 @@ const BasicReport = (props) => {
window.addEventListener('resize', getRefHeight); window.addEventListener('resize', getRefHeight);
return () => window.removeEventListener('resize', getRefHeight); return () => window.removeEventListener('resize', getRefHeight);
}); });
return <div className={style.reportManage} ref={tableWrapperRef}> return (
<div className={style.reportManage} ref={tableWrapperRef}>
{/* 预留容器,提供给点击后的功能显示 */} {/* 预留容器,提供给点击后的功能显示 */}
{ {detailsComponentVisible ? (
detailsComponentVisible ? <DetailsComponent url={detailConfig.url} params={detailConfig.params} <DetailsComponent
onCancel={() => setDetailsComponentVisible(false)} /> : '' url={detailConfig.url}
} params={detailConfig.params}
onCancel={() => setDetailsComponentVisible(false)}
/>
) : (
''
)}
{/* 为方便阅读,分开两部分代码 */} {/* 为方便阅读,分开两部分代码 */}
{ {!detailsComponentVisible ? (
!detailsComponentVisible ? <div className={style.contentWrapper}> <div className={style.contentWrapper}>
{ {state !== 'scan' ? (
state !== 'scan' ? <Row className={style.controlRow} ref={controlRef}> <Row className={style.controlRow} ref={controlRef}>
<Space style={{ flex: 1 }} size={8} wrap={true}> <Space style={{ flex: 1 }} size={8} wrap={true}>
{/*时间搜索控件,确保时间搜索控件在第一个,单独匹配*/} {/*时间搜索控件,确保时间搜索控件在第一个,单独匹配*/}
{ {hasDatePicker &&
hasDatePicker && defaultDateConfig.defaultDate !== null && permission.includes('filters') ? defaultDateConfig.defaultDate !== null &&
permission.includes('filters') ? (
<DatePickerGroup <DatePickerGroup
showModels={['all', 'month', 'quarter', 'year', 'custom']} showModels={['all', 'month', 'quarter', 'year', 'custom']}
onChange={changeDate} onChange={changeDate}
format={dateFormat} format={dateFormat}
defaultModel={defaultDateConfig.defaultModel} defaultModel={defaultDateConfig.defaultModel}
defaultDate={defaultDateConfig.defaultDate} defaultDate={defaultDateConfig.defaultDate}
/> : '' />
} ) : (
{ ''
controls && controls.length && permission.includes('filters') ? )}
controls.filter(control => ['下拉', '多选'].includes(control.filterRule)).map(control => { {controls && controls.length && permission.includes('filters')
return <Form.Item label={control.fieldAlias} key={control.fieldAlias}> ? controls
<ReturnControlComponent style={{ width: 240 }} type={control.filterRule} reportName={reportName} .filter((control) => ['下拉', '多选'].includes(control.filterRule))
.map((control) => {
return (
<Form.Item label={control.fieldAlias} key={control.fieldAlias}>
<ReturnControlComponent
style={{ width: 240 }}
type={control.filterRule}
reportName={reportName}
fieldAlias={control.fieldAlias} fieldAlias={control.fieldAlias}
configItems={control.configItems} configItems={control.configItems}
onChange={(e) => controlSelectChange(control.fieldAlias, e)} /> onChange={(e) => controlSelectChange(control.fieldAlias, e)}
</Form.Item>; />
}) : '' </Form.Item>
} );
{ })
permission.includes('filters') ? <Form.Item label='快速索引' key={'快速搜索控件'}> : ''}
{permission.includes('filters') ? (
<Form.Item label="快速索引" key={'快速搜索控件'}>
<ReturnControlComponent <ReturnControlComponent
placeholder={`请输入${searchPlaceholder.length ? searchPlaceholder.join(',') : '关键字'}搜索`} placeholder={`请输入${
style={{ width: 240 }} type={'文本'} onChange={(e) => { searchPlaceholder.length ? searchPlaceholder.join(',') : '关键字'
}搜索`}
style={{ width: 240 }}
type={'文本'}
onChange={(e) => {
searchInputChange(e); searchInputChange(e);
}} onSearch={searchData} /> }}
</Form.Item> : '' onSearch={searchData}
} />
</Form.Item>
) : (
''
)}
</Space> </Space>
{ {permission.includes('sortBtn') ? (
permission.includes('sortBtn') ? <div style={{ width: 200, textAlign: 'end' }}> <div style={{ width: 200, textAlign: 'end' }}>
<Space size={8} nowrap={true}> <Space size={8} nowrap={true}>
{ {sortModalVisible && permission.includes('sortBtn') ? (
sortModalVisible && permission.includes('sortBtn') ? <Form.Item> <Form.Item>
<Button type={'primary'} title={'自定义排序'} icon={<SortAscendingOutlined />} <Button
onClick={() => setModalVisible(true)}>排序</Button> type={'primary'}
</Form.Item> : '' title={'自定义排序'}
} icon={<SortAscendingOutlined />}
{ onClick={() => setModalVisible(true)}
permission.includes('exportBtn') ? <Form.Item> >
<Dropdown.Button style={{ float: 'right' }} overlay={menu}>导出</Dropdown.Button> 排序
</Form.Item> : '' </Button>
} </Form.Item>
) : (
''
)}
{permission.includes('exportBtn') ? (
<Form.Item>
<Dropdown.Button style={{ float: 'right' }} overlay={menu}>
导出
</Dropdown.Button>
</Form.Item>
) : (
''
)}
</Space> </Space>
</div> : '' </div>
} ) : (
</Row> : '' ''
} )}
<div className={style.tableContent} </Row>
style={{ height: `calc(100% - ${controlsHeight || 0}px)` }}> ) : (
{ ''
columns && columns.length ? <BasicTable )}
<div
className={style.tableContent}
style={{ height: `calc(100% - ${controlsHeight || 0}px)` }}
>
{columns && columns.length ? (
<BasicTable
rowKey={'Key'} rowKey={'Key'}
bordered bordered
loading={tableLoading} loading={tableLoading}
dataSource={tableData} dataSource={tableData}
columns={columns} columns={columns}
onChange={(pagination, filters, sorter, extra)=>{ onChange={(pagination, filters, sorter, extra) => {
console.log(sorter) console.log(sorter);
}} }}
pagination={permission.includes('pagination') ? pagination : false} pagination={permission.includes('pagination') ? pagination : false}
// 237是内置图片高度 // 237是内置图片高度
scroll={{ y: (tableData && tableData.length) ? `calc(100% - 44px)` : 237, x: tableX }} scroll={{ y: tableData && tableData.length ? `calc(100% - 44px)` : 237, x: tableX }}
summary={(pageData) => { summary={(pageData) => {
if (summaryArray.length && tableData && tableData.length) return <Table.Summary fixed> if (summaryArray.length && tableData && tableData.length)
return (
<Table.Summary fixed>
<Table.Summary.Row> <Table.Summary.Row>
{ {hasSinglePage
hasSinglePage ? ? summaryArray.map((item, index) => {
summaryArray.map((item, index) => {
if (item.fieldName === '空值行0') { if (item.fieldName === '空值行0') {
return <Table.Summary.Cell key={`summary_${index}`} index={0} return (
colSpan={item.colSpan + 1}><span <Table.Summary.Cell
key={`summary_${index}`}
index={0}
colSpan={item.colSpan + 1}
>
<span
style={{ style={{
display: 'inline-block', display: 'inline-block',
width: '100%', width: '100%',
textAlign: 'center', textAlign: 'center',
}}>小计</span></Table.Summary.Cell>; }}
>
小计
</span>
</Table.Summary.Cell>
);
} else if (item.fieldName.includes('空值行')) { } else if (item.fieldName.includes('空值行')) {
return <Table.Summary.Cell key={`summary_${index}`} index={0} colSpan={item.colSpan} />; return (
<Table.Summary.Cell
key={`summary_${index}`}
index={0}
colSpan={item.colSpan}
/>
);
} else { } else {
return <Table.Summary.Cell key={`summary_${index}`} index={0}><span style={{ return (
<Table.Summary.Cell key={`summary_${index}`} index={0}>
<span
style={{
display: 'inline-block', display: 'inline-block',
width: '100%', width: '100%',
textAlign: item.alignType, textAlign: item.alignType,
}}>{item.type.replace('求', '')}: {returnHandledNumber(item.configItems, item['单页'])}</span></Table.Summary.Cell>; }}
} >
}) : '' {item.type.replace('求', '')}:{' '}
{returnHandledNumber(item.configItems, item['单页'])}
</span>
</Table.Summary.Cell>
);
} }
})
: ''}
</Table.Summary.Row> </Table.Summary.Row>
<Table.Summary.Row> <Table.Summary.Row>
{ {hasTotal
hasTotal ? ? summaryArray.map((item) => {
summaryArray.map(item => {
if (item.fieldName === '空值行0') { if (item.fieldName === '空值行0') {
return <Table.Summary.Cell index={0} colSpan={item.colSpan + 1}><span style={{ return (
<Table.Summary.Cell index={0} colSpan={item.colSpan + 1}>
<span
style={{
display: 'inline-block', display: 'inline-block',
width: '100%', width: '100%',
textAlign: 'center', textAlign: 'center',
}}>总计</span></Table.Summary.Cell>; }}
>
总计
</span>
</Table.Summary.Cell>
);
} else if (item.fieldName.includes('空值行')) { } else if (item.fieldName.includes('空值行')) {
return <Table.Summary.Cell index={0} colSpan={item.colSpan} />; return <Table.Summary.Cell index={0} colSpan={item.colSpan} />;
} else { } else {
return <Table.Summary.Cell index={0}><span style={{ return (
<Table.Summary.Cell index={0}>
<span
style={{
display: 'inline-block', display: 'inline-block',
width: '100%', width: '100%',
textAlign: item.alignType, textAlign: item.alignType,
}}>{item.type.replace('求', '')}: {returnHandledNumber(item.configItems, item['全部'])}</span></Table.Summary.Cell>; }}
} >
}) : '' {item.type.replace('求', '')}:{' '}
{returnHandledNumber(item.configItems, item['全部'])}
</span>
</Table.Summary.Cell>
);
} }
})
: ''}
</Table.Summary.Row> </Table.Summary.Row>
</Table.Summary>; </Table.Summary>
);
}} }}
/> : <div className={style.spinWrapper}> />
) : (
<div className={style.spinWrapper}>
<Spin /> <Spin />
</div> </div>
} )}
</div> </div>
</div> : '' </div>
} ) : (
''
)}
<Modal <Modal
title={'自定义排序字段'} title={'自定义排序字段'}
visible={modalVisible} visible={modalVisible}
...@@ -875,53 +1011,67 @@ const BasicReport = (props) => { ...@@ -875,53 +1011,67 @@ const BasicReport = (props) => {
footer={ footer={
<div style={{ display: 'flex', justifyContent: 'space-between' }}> <div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div> <div>
<Button type={'link'} onClick={() => addOtherSortFields()}>增加次要排序</Button> <Button type={'link'} onClick={() => addOtherSortFields()}>
增加次要排序
</Button>
</div> </div>
<div> <div>
<Button onClick={() => setModalVisible(false)}>取消</Button> <Button onClick={() => setModalVisible(false)}>取消</Button>
<Button type={'primary'} onClick={() => { <Button
type={'primary'}
onClick={() => {
saveReportListSortFields(() => getData(false, pagination)); saveReportListSortFields(() => getData(false, pagination));
setModalVisible(false); setModalVisible(false);
}}>确认</Button> }}
>
确认
</Button>
</div> </div>
</div> </div>
} }
> >
{ {selectedSortFields.map((item, index) => (
selectedSortFields.map((item, index) => <Row key={'label'} className={style.controlRow}> <Row key={'label'} className={style.controlRow}>
<Space size={8} wrap={true}> <Space size={8} wrap={true}>
<Form.Item label={item.label}> <Form.Item label={item.label}>
<Select style={{ width: 240 }} defaultValue={item.value} value={item.value} <Select
onChange={(e) => changeSortField(e, index, 'value')}> style={{ width: 240 }}
<Option value=''>未选择</Option> defaultValue={item.value}
{ value={item.value}
allSortFields.map(item => <Option value={item}>{item}</Option>) onChange={(e) => changeSortField(e, index, 'value')}
} >
<Option value="">未选择</Option>
{allSortFields.map((item) => (
<Option value={item}>{item}</Option>
))}
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
<Select style={{ width: 120 }} defaultValue={item.sort} value={item.sort} <Select
onChange={(e) => changeSortField(e, index, 'sort')}> style={{ width: 120 }}
defaultValue={item.sort}
value={item.sort}
onChange={(e) => changeSortField(e, index, 'sort')}
>
<Option value={'asc'}>升序</Option> <Option value={'asc'}>升序</Option>
<Option value={'desc'}>降序</Option> <Option value={'desc'}>降序</Option>
</Select> </Select>
</Form.Item> </Form.Item>
{ {index !== 0 ? (
index !== 0 ?
<Form.Item> <Form.Item>
<MinusCircleOutlined style={{ color: 'rgba(0,0,0,.65)' }} onClick={() => deleteSortField(index)} /> <MinusCircleOutlined
</Form.Item> : '' style={{ color: 'rgba(0,0,0,.65)' }}
} onClick={() => deleteSortField(index)}
/>
</Form.Item>
) : (
''
)}
</Space> </Space>
</Row>) </Row>
} ))}
</Modal> </Modal>
<Modal <Modal visible={extraModal} onCancel={() => setExtraModal(false)} destroyOnClose width={800}>
visible={extraModal}
onCancel={() => setExtraModal(false)}
destroyOnClose
width={800}
>
{extra} {extra}
</Modal> </Modal>
{/* 编辑表单 */} {/* 编辑表单 */}
...@@ -933,18 +1083,24 @@ const BasicReport = (props) => { ...@@ -933,18 +1083,24 @@ const BasicReport = (props) => {
// visible={true} // visible={true}
onCancel={() => setEditComponentVisible(false)} onCancel={() => setEditComponentVisible(false)}
> >
<ReportEditForm reportDetails={tableStruct} reportData={currentData} onCancel={() => { <ReportEditForm
reportDetails={tableStruct}
reportData={currentData}
onCancel={() => {
setEditComponentVisible(false); setEditComponentVisible(false);
getData(false, pagination); getData(false, pagination);
}} reportName={reportName} /> }}
reportName={reportName}
/>
</Modal> </Modal>
</div>; </div>
);
}; };
const mapStateToProps = state => { const mapStateToProps = (state) => {
const allWidgets = state.getIn(['global', 'globalConfig', 'allWidgets']); const allWidgets = state.getIn(['global', 'globalConfig', 'allWidgets']);
let _flatWidgets = []; let _flatWidgets = [];
const flatWidgets = (arr) => { const flatWidgets = (arr) => {
arr.forEach(item => { arr.forEach((item) => {
if (item.widgets && item.widgets.length) { if (item.widgets && item.widgets.length) {
flatWidgets(item.widgets); flatWidgets(item.widgets);
} else { } else {
......
@import "~antd/es/style/themes/default.less"; @import '~antd/es/style/themes/default.less';
.lackParams { .lackParams {
width: 100%;
height: 100%;
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
justify-content: center;
width: 100%;
height: 100%;
} }
.reportManage { .reportManage {
padding: 8px;
height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%;
padding: 8px;
.contentWrapper { .contentWrapper {
display: flex; display: flex;
...@@ -20,12 +20,12 @@ ...@@ -20,12 +20,12 @@
height: 100%; height: 100%;
.controlRow { .controlRow {
background: #ffffff;
padding: 6px;
border-radius: 4px;
margin-bottom: 4px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
margin-bottom: 4px;
padding: 6px;
background: #ffffff;
border-radius: 4px;
} }
.tableContent { .tableContent {
...@@ -46,8 +46,8 @@ ...@@ -46,8 +46,8 @@
} }
.deleteButton { .deleteButton {
cursor: pointer;
color: rgb(255, 0, 0); color: rgb(255, 0, 0);
cursor: pointer;
&:hover { &:hover {
//color: rgb(24, 144, 255); //color: rgb(24, 144, 255);
...@@ -56,25 +56,24 @@ ...@@ -56,25 +56,24 @@
} }
.spinWrapper { .spinWrapper {
width: 100vw;
height: 60vh;
display: flex; display: flex;
align-items: center;
justify-content: center; justify-content: center;
align-items: center width: 100vw;
height: 60vh;
} }
:global { :global {
.@{ant-prefix}-table-container { .@{ant-prefix}-table-container {
height: 100%; height: 100%;
& > .@{ant-prefix}-table-body { & > .@{ant-prefix}-table-body {
border-bottom: 1px solid #dbe7fb;
border-right: 1px solid #dbe7fb; border-right: 1px solid #dbe7fb;
border-bottom: 1px solid #dbe7fb;
} }
.@{ant-prefix}-table-body { .@{ant-prefix}-table-body {
flex: 1 flex: 1;
} }
.@{ant-prefix}-table-summary > table > tfoot > tr > td { .@{ant-prefix}-table-summary > table > tfoot > tr > td {
...@@ -97,7 +96,6 @@ ...@@ -97,7 +96,6 @@
} }
} }
.link { .link {
cursor: pointer; cursor: pointer;
...@@ -115,7 +113,7 @@ ...@@ -115,7 +113,7 @@
} }
.prefixOrSuffix { .prefixOrSuffix {
color: rgba(0, 0, 0, .65); color: rgba(0, 0, 0, 0.65);
font-size: 10px; font-size: 10px;
} }
...@@ -128,14 +126,14 @@ ...@@ -128,14 +126,14 @@
::-webkit-scrollbar-track, ::-webkit-scrollbar-track,
*::-webkit-scrollbar-track { *::-webkit-scrollbar-track {
background: #F2F2F2; background: #f2f2f2;
border-radius: 10px; border-radius: 10px;
} }
::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb,
*::-webkit-scrollbar-thumb { *::-webkit-scrollbar-thumb {
background: #dcdcdc;
border-radius: 5px; border-radius: 5px;
background: #DCDCDC;
} }
} }
} }
...@@ -13,14 +13,14 @@ const isArray = (arr) => { ...@@ -13,14 +13,14 @@ const isArray = (arr) => {
const hasMoney = (configItems) => { const hasMoney = (configItems) => {
if (!configItems) return false; if (!configItems) return false;
let _items = configItems.split('|'); let _items = configItems.split('|');
return !!_items.find(item => item === '金额'); return !!_items.find((item) => item === '金额');
}; };
/** /**
* @Description: 用来在summary中处理数值的配置 * @description: 用来在summary中处理数值的配置
* @Params: 参数描述 * @params: 参数描述
* @Date: 2022/8/10 * @date: 2022/8/10
* @Author: ChenLong * @author: ChenLong
* */ */
const returnHandledNumber = (configItems, num) => { const returnHandledNumber = (configItems, num) => {
// 精度、前缀、后缀、倍率 // 精度、前缀、后缀、倍率
// $_d|_d%|_d*0.0001|金额|0.00 // $_d|_d%|_d*0.0001|金额|0.00
...@@ -31,7 +31,7 @@ const returnHandledNumber = (configItems, num) => { ...@@ -31,7 +31,7 @@ const returnHandledNumber = (configItems, num) => {
let template = '_d'; let template = '_d';
let precision = 0; let precision = 0;
let rate = 1; let rate = 1;
_items.forEach(item => { _items.forEach((item) => {
let _arr = []; let _arr = [];
if (item.match(/_d[^\*]/)) { if (item.match(/_d[^\*]/)) {
// 后缀 // 后缀
...@@ -46,30 +46,40 @@ const returnHandledNumber = (configItems, num) => { ...@@ -46,30 +46,40 @@ const returnHandledNumber = (configItems, num) => {
} }
}); });
// 可能存在NaN的问题 // 可能存在NaN的问题
let final = _items.includes('金额') ? Number((num * rate).toFixed(precision)).toLocaleString() : Number((num * rate).toFixed(precision)); let final = _items.includes('金额')
? Number((num * rate).toFixed(precision)).toLocaleString()
: Number((num * rate).toFixed(precision));
return template.replace(/_d/, final); return template.replace(/_d/, final);
}; };
/** /**
* @Description: 返回configItems内配置的默认值、默认模式等等 * @description: 返回configItems内配置的默认值、默认模式等等
* @Params: 参数描述 * @params: 参数描述
* @Date: 2022/8/12 * @date: 2022/8/12
* @Author: ChenLong * @author: ChenLong
* @params: * @params:
* configItems 报表字段的配置 例如 defaultValue=智慧水务 defaultDateModel=customer|defaultDateValue=2022-01-01,2022-12-31; * configItems 报表字段的配置 例如 defaultValue=智慧水务
* keysArray 所需要返回的值的key的集合,比如你需要获取configItems中的’defaultValue‘,那么keysArray=['defaultValue']; * defaultDateModel=customer|defaultDateValue=2022-01-01,2022-12-31;
* @Returns: * keysArray
* 所需要返回的值的key的集合,比如你需要获取configItems中的’defaultValue‘,那么keysArray=['defaultValue'];
* @returns:
* defaultValue 通用参数 默认值 * defaultValue 通用参数 默认值
* defaultDateModel 时间参数 默认模式 * defaultDateModel 时间参数 默认模式
* defaultDateValue 时间参数 默认时间 * defaultDateValue 时间参数 默认时间
* */ */
const returnDefaultValueOrConfigs = (configItems = '', keysArray = []) => { const returnDefaultValueOrConfigs = (configItems = '', keysArray = []) => {
let _map = {}; let _map = {};
let _configItemsArray = configItems.split('|'); let _configItemsArray = configItems.split('|');
keysArray.forEach(key => { keysArray.forEach((key) => {
_map[key] = _configItemsArray.find(item => item.includes(`${key}=`))?.replace(`${key}=`, ''); _map[key] = _configItemsArray.find((item) => item.includes(`${key}=`))?.replace(`${key}=`, '');
}); });
return _map; return _map;
}; };
export { export {
isObject, isString, isNumber, hasMoney, isArray, returnHandledNumber, returnDefaultValueOrConfigs, isObject,
isString,
isNumber,
hasMoney,
isArray,
returnHandledNumber,
returnDefaultValueOrConfigs,
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment