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