Commit 561f975d authored by 陈龙's avatar 陈龙

feat: 新增报表组件

parent fb2e80f0
......@@ -147,7 +147,6 @@
"@wisdom-components/basictable": "^1.5.14",
"@wisdom-components/empty": "^1.3.9",
"@wisdom-components/exportexcel": "^1.1.2",
"@wisdom-components/rich": "file:packages/base-components/rich",
"@wisdom-components/timerangepicker": "^1.3.4",
"@wisdom-utils/utils": "0.0.46",
"classnames": "^2.2.6",
......
......@@ -7,7 +7,7 @@
import React, { useEffect, useState } from 'react';
import { Form, Input, DatePicker, InputNumber, Space, Row, Col, Button, message } from 'antd';
import moment from 'moment';
import { submitReportData } from '../../../api/service/report';
import { submitReportData } from './api/service/report';
// 类型
const DATE_PICKER_ARRAY = ['日期'];
const DATE_TIME_PICKER_ARRAY = ['日期时刻'];
......@@ -18,12 +18,12 @@ const NUMBER_ARRAY = ['数值', '金额'];
// 对应关系
/**
* @Description: 函数描述
* @Date: 2022/8/10
* @Author: ChenLong
* @Params: reportDetails 各个字段的配置列表
* @description: 函数描述
* @date: 2022/8/10
* @author: ChenLong
* @params: reportDetails 各个字段的配置列表
* data 与reportDetails对应的值
* */
*/
const ReportEditForm = ({ reportDetails, reportData, onCancel, reportName }) => {
if (!reportData || Object.keys(reportData).length === 0) return <>未传递表单数据</>;
const [form] = Form.useForm();
......@@ -37,7 +37,7 @@ const ReportEditForm = ({ reportDetails, reportData, onCancel, reportName }) =>
};
const handleDate = (reportDetails, data) => {
let _data = { ...data };
reportDetails.forEach(item => {
reportDetails.forEach((item) => {
if (DATE_TYPE.includes(item.type)) {
_data[item.fieldAlias] = moment(data[item.fieldAlias]);
}
......@@ -64,7 +64,7 @@ const ReportEditForm = ({ reportDetails, reportData, onCancel, reportName }) =>
// "fieldValue": "string"
// }
let final = [];
Object.keys(_data).forEach(key => {
Object.keys(_data).forEach((key) => {
let value = reportData[key];
let _value = _data[key];
if (moment.isMoment(_data[key])) {
......@@ -80,10 +80,13 @@ const ReportEditForm = ({ reportDetails, reportData, onCancel, reportName }) =>
});
console.log(final);
// reportService.updateReportData()
submitReportData({
reportName: reportName,
userId: window.globalConfig.userInfo.OID,
}, final).then(res => {
submitReportData(
{
reportName: reportName,
userId: window.globalConfig.userInfo.OID,
},
final,
).then((res) => {
if (res.code === 0) {
message.success('保存成功!');
onCancel();
......@@ -91,26 +94,30 @@ const ReportEditForm = ({ reportDetails, reportData, onCancel, reportName }) =>
});
};
useEffect(() => {
if (reportData && Object.keys(reportData).length) form.setFieldsValue(handleDate(reportDetails, reportData));
if (reportData && Object.keys(reportData).length)
form.setFieldsValue(handleDate(reportDetails, reportData));
}, [reportData]);
return (
<div>
<Form {...formItemLayout} form={form}>
<Row>
{
reportDetails && reportDetails.map(config => {
return <Col span={8}>
<Form.Item label={config.fieldAlias} name={config.fieldAlias}>
{componentMap(config)}
</Form.Item>
</Col>;
})
}
{reportDetails &&
reportDetails.map((config) => {
return (
<Col span={8}>
<Form.Item label={config.fieldAlias} name={config.fieldAlias}>
{componentMap(config)}
</Form.Item>
</Col>
);
})}
</Row>
<Row>
<Col span={24} style={{textAlign:'right'}}>
<Col span={24} style={{ textAlign: 'right' }}>
{/*<Form.Item style={{textAlign:'right'}}>*/}
<Button type={'primary'} onClick={submitReportForm}>提交</Button>
<Button type={'primary'} onClick={submitReportForm}>
提交
</Button>
{/*</Form.Item>*/}
</Col>
</Row>
......
......@@ -2,12 +2,7 @@ import { Modal, notification } from 'antd';
import { instanceRequest, service } from '@wisdom-utils/utils';
import AppService from './service/base';
import notificationService from './service/notification';
import AccountService from './service/account';
import AssetService from './service/asset';
import ReportService from './service/report';
// import WorkflowService from './service/workflow';
const { warning } = Modal;
// eslint-disable-next-line no-return-await
......@@ -32,7 +27,7 @@ const codeMessage = {
};
let instance = null;
instanceRequest.setErrorHandler(error => {
instanceRequest.setErrorHandler((error) => {
const { response } = error;
if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
......@@ -44,9 +39,7 @@ instanceRequest.setErrorHandler(error => {
content: `${codeMessage[status]}`,
centered: true,
onOk(close) {
window.share &&
window.share.event &&
window.share.event.emit('triggerLoginout');
window.share && window.share.event && window.share.event.emit('triggerLoginout');
close();
},
});
......@@ -66,18 +59,5 @@ instanceRequest.setErrorHandler(error => {
return response;
});
const appService = service(AppService);
const noticeService = service(notificationService);
const accountService = service(AccountService);
const assetService = service(AssetService);
// const workflowService = service(WorkflowService);
const reportService = service(ReportService);
export {
appService,
noticeService,
accountService,
assetService,
// workflowService
reportService
};
export { reportService };
// 文本/下拉/多选/时间
/**
* @Description:
* @Params:
* onChange: 需要传入onChange,接收值的变更
* */
* @description:
* @params:
* onChange: 需要传入onChange,接收值的变更
*/
import React, { useEffect, useState } from 'react';
import { Input, Select } from 'antd';
import { reportService } from '@/api';
import { reportService } from '../api';
import { returnDefaultValueOrConfigs } from '../utils/utils';
const { Option } = Select;
const { Search } = Input;
const TextSearchComponent = ({ onChange, style, onSearch, placeholder }) => {
return <Search title={placeholder} style={style} placeholder={placeholder} onChange={onChange} onSearch={onSearch} />;
return (
<Search
title={placeholder}
style={style}
placeholder={placeholder}
onChange={onChange}
onSearch={onSearch}
/>
);
};
/**
* data = ['选项1','选项2'...]
* @Props:
* 正常选项:武汉
* 附带统计数值: 武汉 (20)
* Data = ['选项1','选项2'...]
*
* */
const SelectSearchComponent = ({ onChange, style, data, mode, reportName, fieldAlias, configItems }) => {
const [value,setValue] = useState('');
* @props:
* 正常选项:武汉
* 附带统计数值: 武汉 (20)
*/
const SelectSearchComponent = ({
onChange,
style,
data,
mode,
reportName,
fieldAlias,
configItems,
}) => {
const [value, setValue] = useState('');
const [options, setOptions] = useState([]);
const defaultConfigs = returnDefaultValueOrConfigs(configItems, ['defaultValue']);
const { defaultValue } = defaultConfigs;
const getData = () => {
reportService.getReportFilterValue({
reportName,
fieldAlias,
}).then(res => {
if (res.code === 0) {
setOptions(res.data);
}
}).catch(err => {
console.log(err);
});
reportService
.getReportFilterValue({
reportName,
fieldAlias,
})
.then((res) => {
if (res.code === 0) {
setOptions(res.data);
}
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
getData();
setValue(defaultValue)
setValue(defaultValue);
}, []);
return <Select
value={value}
style={style}
onChange={(e) => {
onChange(e);
setValue(e);
}}
mode={mode}
defaultValue={mode === 'multiple' ? defaultValue.split(',') : defaultValue}
allowClear
maxTagCount={1}
placeholder={`请选择${fieldAlias}`}
>
{
options && options.length ?
options.map(
item => <Option key={item.filterValue} value={item.filterValue}>{item.filterValue} <span
style={{ color: 'rgba(0,0,0,.65)' }}>({item.count})</span></Option>,
) : ''
}
</Select>;
return (
<Select
value={value}
style={style}
onChange={(e) => {
onChange(e);
setValue(e);
}}
mode={mode}
defaultValue={mode === 'multiple' ? defaultValue.split(',') : defaultValue}
allowClear
maxTagCount={1}
placeholder={`请选择${fieldAlias}`}
>
{options && options.length
? options.map((item) => (
<Option key={item.filterValue} value={item.filterValue}>
{item.filterValue} <span style={{ color: 'rgba(0,0,0,.65)' }}>({item.count})</span>
</Option>
))
: ''}
</Select>
);
};
const ReturnControlComponent = ({
type,
onChange,
style,
data,
onSearch,
reportName,
fieldAlias,
placeholder,
configItems,
}) => {
type,
onChange,
style,
data,
onSearch,
reportName,
fieldAlias,
placeholder,
configItems,
}) => {
let _component = '';
switch (type) {
case '文本':
_component =
<TextSearchComponent style={style} onChange={onChange} onSearch={onSearch} placeholder={placeholder}
configItems={configItems} />;
_component = (
<TextSearchComponent
style={style}
onChange={onChange}
onSearch={onSearch}
placeholder={placeholder}
configItems={configItems}
/>
);
break;
case '下拉':
case '多选':
_component =
<SelectSearchComponent mode={type === '多选' ? 'multiple' : ''} style={style} onChange={onChange}
reportName={reportName} fieldAlias={fieldAlias} configItems={configItems} />;
_component = (
<SelectSearchComponent
mode={type === '多选' ? 'multiple' : ''}
style={style}
onChange={onChange}
reportName={reportName}
fieldAlias={fieldAlias}
configItems={configItems}
/>
);
break;
default:
break;
......
import style from '../ReportsManage.less';
import style from '../index.less';
import extraComponents from '../extra/extraComponents';
import moment from 'moment';
import { Tag } from 'antd';
import { hasMoney, isNumber } from './utils';
/**
* @Params: config下的数值的configRule结构如下,[{最大值: 10,最小值: 0,颜色:'#AAAAAA'}];
* @business: configRule有值,则按照configRule设置;没有,按照color设置;
* 有最大值,无最小值;['', 1]
* 有最大值,有最小值;[2, 10]
* @params: config下的数值的configRule结构如下,[{最大值: 10,最小值: 0,颜色:'#AAAAAA'}];
* @business: configRule有值,则按照configRule设置;没有,按照color设置; 有最大值,无最小值;['', 1]
* 有最大值,有最小值;[2,
* 10]
* 有最小值,无最大值;[11,'']
* */
*/
// 链接 功能 弹窗功能待提出需求
// 函数名、属性、...
const clickLink = (config) => {
return window.open(config.configItems, '_blank');
};
const handleUrl = (allWidgets, config) => {
};
const handleUrl = (allWidgets, config) => {};
const handleConfigUrl = (config, record) => {
let _configs = config.configItems.split('|');
// type = 替换|跳转;
// type = 替换|跳转;
let _type = '';
//url=project/pandawork/contractDetails/index?ageSize=100&accountName=软件订单台账|contractCode=${订单编号}|company=${分公司}
//url=project/pandawork/contractDetails/index?ageSize=100&accountName=软件订单台账|contractCode=${订单编号}|company=${分公司}
let _url = '';
let _params = {};
_configs.forEach(item => {
_configs.forEach((item) => {
if (item.includes('type=')) _type = item.replace('type=', '');
if (item.includes('url=')) {
let _tempUrl = item.replace('url=', '');
let _urlArray = _tempUrl.split('?');
if (_urlArray[1]) {
_urlArray[1].split('&').forEach(param => {
_urlArray[1].split('&').forEach((param) => {
let _paramArr = param.split('=');
if (_paramArr[1] && _paramArr[1].includes('${') && _paramArr[1].includes('}')) {
let _key = _paramArr[1].replace(/\$\{|\}/g, '');
......@@ -62,7 +60,7 @@ const clickModal = (config, showModal, setExtra) => {
let _fn = _splitArr[0] || 'default';
_splitArr.splice(0, 1);
let _data = {};
_splitArr.forEach(item => {
_splitArr.forEach((item) => {
let _item = item.split('=');
_data[_item[0]] = _item[1];
});
......@@ -80,7 +78,8 @@ export const handleNumber = (config, number) => {
let _color = '';
if (number) number = Number(number); // 当设置精度后,会被转成字符串
if (config.numericalConfigs && config.numericalConfigs.length) {
config.numericalConfigs.forEach(item => { // 接口对于数值类型的返回为null
config.numericalConfigs.forEach((item) => {
// 接口对于数值类型的返回为null
if (!_color) {
let _max = item.maxValue || '';
let _min = item.minValue || '';
......@@ -96,39 +95,58 @@ export const handleNumber = (config, number) => {
} else if (config.color) {
_color = config.color;
}
return number ? <span>
<span className={style.prefixOrSuffix} style={{
color: _color,
}}>{config.prefix || ''}</span>
<span style={{
color: _color,
margin: '0 5px',
}}>{hasMoney(config?.configItems) ? (number ? Number(number)?.toLocaleString() : number) : number}</span>
<span className={style.prefixOrSuffix} style={{ color: _color }}>{config.suffix || ''}</span>
</span> : '-';
return number ? (
<span>
<span
className={style.prefixOrSuffix}
style={{
color: _color,
}}
>
{config.prefix || ''}
</span>
<span
style={{
color: _color,
margin: '0 5px',
}}
>
{hasMoney(config?.configItems)
? number
? Number(number)?.toLocaleString()
: number
: number}
</span>
<span className={style.prefixOrSuffix} style={{ color: _color }}>
{config.suffix || ''}
</span>
</span>
) : (
'-'
);
};
/**
* @Params: 标签形态的configRule,[{标签值:'字符串',颜色: '#AAAAAA'}];
* */
/** @params: 标签形态的configRule,[{标签值:'字符串',颜色: '#AAAAAA'}]; */
export const handleTag = (config, text) => {
let _color = '';
let _map = {};
// 标签需要设置分隔符 2022年7月13日 ChenLong
let _configItems = config.configItems.split('|');
let _configMap = {};
_configItems.forEach(item => {
_configItems.forEach((item) => {
let _arr = item.split('=');
_configMap[_arr[0]] = _arr[1];
});
// 处理label的颜色
if (config.labelConfigs && config.labelConfigs.length) {
config.labelConfigs.forEach(item => {
config.labelConfigs.forEach((item) => {
_map[item.labelValue] = item.color;
});
}
_color = config.color || 'rgba(0,0,0,.85)';
// String(text)为了解决可能存在数值类型的数据需要设置成标签的需求
return String(text).split(_configMap['分隔符']).map(item => <Tag color={_map[item]}>{item}</Tag>);
return String(text)
.split(_configMap['分隔符'])
.map((item) => <Tag color={_map[item]}>{item}</Tag>);
/* return String(text).split(_configMap['分隔符']).map(item => <Tag style={{
background: _map[item] || _color,
border: `1px solid ${_map[item]}`,
......@@ -140,17 +158,39 @@ export const handleText = (config, text) => {
return <span style={{ color: config.color || 'rgba(0,0,0,.85)' }}>{text}</span>;
};
export const handleLink = (config, text) => {
return <span className={style.link} style={{
color: config.color || 'rgba(0,0,0,.85)',
}} onClick={() => clickLink(config)}>{text}</span>;
return (
<span
className={style.link}
style={{
color: config.color || 'rgba(0,0,0,.85)',
}}
onClick={() => clickLink(config)}
>
{text}
</span>
);
};
export const handleWidget = (config, text, record, showComponents, setDetailsConfig) => {
return <span style={{ color: config.color }} className={style.link}
onClick={() => clickWidget(config, text, record, showComponents, setDetailsConfig)}>{text}</span>;
return (
<span
style={{ color: config.color }}
className={style.link}
onClick={() => clickWidget(config, text, record, showComponents, setDetailsConfig)}
>
{text}
</span>
);
};
export const handleModal = (config, text, showModal, setExtra) => {
return <span className={style.link} style={{ color: config.color || 'rgba(0,0,0,.85)' }}
onClick={() => clickModal(config, showModal, setExtra)}>{text}</span>;
return (
<span
className={style.link}
style={{ color: config.color || 'rgba(0,0,0,.85)' }}
onClick={() => clickModal(config, showModal, setExtra)}
>
{text}
</span>
);
};
// 日期
export const handleDateString = (config, text) => {
......@@ -166,5 +206,5 @@ export const handlePageSize = (numStr) => {
};
// 处理默认排序
export const handleSortFields = (sortFields) => {
return sortFields && sortFields.split(',')
}
return sortFields && sortFields.split(',');
};
This source diff could not be displayed because it is too large. You can view the blob instead.
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