Commit 48ac1217 authored by 陈龙's avatar 陈龙

feat: 提交报表代码

parent e7a194d1
# Change Log
All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.8.2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.8.0...@wisdom-components/basicreport@1.8.2) (2022-12-13)
### Bug Fixes
- 修复函数未引用导致的 bug ([3f3eb57](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/3f3eb57d01d9d97a0e1c5b836cef09e93d1193b1))
- 修复函数未引用导致的 bug ([07038a2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/07038a22afd57b8935ea6cdb6c3fd761f14f3ff0))
## [1.8.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.8.0...@wisdom-components/basicreport@1.8.1) (2022-12-13)
### Bug Fixes
- 修复函数未引用导致的 bug ([07038a2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/07038a22afd57b8935ea6cdb6c3fd761f14f3ff0))
# [1.8.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.7.0...@wisdom-components/basicreport@1.8.0) (2022-12-07)
### Features
- 更新轻量化报表 ([3985ad9](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/3985ad9af1a9d3130ad07eab0cb959a820a73fad))
# [1.7.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.6.0...@wisdom-components/basicreport@1.7.0) (2022-12-07)
### Features
- 更新轻量化报表功能 ([d73f0e6](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/d73f0e6c84d5633af7cfe3d4bf3c234bcaa8f2c9))
# [1.6.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.5.0...@wisdom-components/basicreport@1.6.0) (2022-09-13)
### Features
- 更新 baiscreport 版本 ([fa63f24](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/fa63f244ddcc23f4fe11dd78acd8d9fcc8b3cc8a))
- 优化默认筛选值的逻辑,现在可以配置多个筛选值 ([62f7fed](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/62f7fed834d31526b8fb33868fad905bf45de4fc))
# [1.5.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.4.0...@wisdom-components/basicreport@1.5.0) (2022-09-13)
### Features
- 实现选择器 ([9df6ec8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/9df6ec87a429fe9c8d321a6f7bc4a5677b852b7f))
# [1.4.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.3.1...@wisdom-components/basicreport@1.4.0) (2022-09-07)
### Bug Fixes
- 修复组件引入错误 ([31facdf](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/31facdf92b6200c3ceac31fb549a77faa4a68434))
### Features
- 新增 demo ([0ffab69](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/0ffab69ab677d377ce861e1ab9205ab8b78464a4))
## [1.3.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.3.0...@wisdom-components/basicreport@1.3.1) (2022-09-06)
### Bug Fixes
- 修复路径错误 ([c7d8fa8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/c7d8fa8230f1f47478010e8e1263b1aa46703311))
# [1.3.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.2.3...@wisdom-components/basicreport@1.3.0) (2022-09-05)
### Features
- 新增大量功能 ([437dd7c](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/437dd7ca8cb83552b88e11585bb9b7040ee6b07e))
## [1.2.3](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.2.2...@wisdom-components/basicreport@1.2.3) (2022-08-29)
### Bug Fixes
- 兼容日期为 null 的情况 ([0ef2dfb](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/0ef2dfb65a938134d8ecea589479ccc99c7c7b93))
## [1.2.2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.2.1...@wisdom-components/basicreport@1.2.2) (2022-08-18)
### Bug Fixes
- fix ([bc49887](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/bc498875cbd3deb3104ff5d61c99cb3c318ba355))
## [1.2.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.2.0...@wisdom-components/basicreport@1.2.1) (2022-08-18)
### Bug Fixes
- 修复数据格式导致的报错;修复路径引入导致的报错 ([6014c40](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/6014c40b6b19f9060b69e95ce729dcdfc2935521))
# [1.2.0](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.1.3...@wisdom-components/basicreport@1.2.0) (2022-08-18)
### Features
- 重新处理报表逻辑 ([3ebe719](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/3ebe71907d0b60988a53c7b641189f748490826b))
## [1.1.3](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.1.2...@wisdom-components/basicreport@1.1.3) (2022-08-17)
### Bug Fixes
- 重新发布 ([2776cf9](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/2776cf9dd8f7520a84c00fad5500da38ec42dc8f))
## [1.1.2](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.1.1...@wisdom-components/basicreport@1.1.2) (2022-08-17)
### Bug Fixes
- 删除无效引用 ([372c06f](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/372c06f3233ab5e48d6b104addfb6ba95e43d847))
## [1.1.1](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/compare/@wisdom-components/basicreport@1.1.0...@wisdom-components/basicreport@1.1.1) (2022-08-17)
### Bug Fixes
- 修复文件引用错误 ([7e486a8](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/7e486a8a6c321fd36d89e78975c4e65002f7eaa2))
# 1.1.0 (2022-08-17)
### Features
- 新增报表组件 ([561f975](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/561f975db85081d678854c94e859406903f71438))
- 新增 BasicReport ([fb2e80f](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/fb2e80f00b130f48e743de5dd4781913e7ff4c01))
- 增加 package.json ([e10973a](https://g.civnet.cn:8443/ReactWeb5/wisdom-components/commits/e10973a31059ceab4b2e01dda56fdd54ade270bc))
{
"name": "@wisdom-components/basicreport",
"version": "1.8.2",
"description": "> TODO: description",
"author": "chenlong <857265978@163.com>",
"homepage": "",
"license": "ISC",
"sideEffects": [
"*.less"
],
"module": "es/index.js",
"main": "es/index.js",
"files": [
"lib",
"es",
"dist"
],
"directories": {
"lib": "lib",
"es": "es",
"dist": "dist",
"test": "__tests__"
},
"publishConfig": {
"registry": "https://g.civnet.cn:4873/"
},
"repository": {
"type": "git",
"url": "https://g.civnet.cn:8443/ReactWeb5/wisdom-components.git"
},
"scripts": {
"test": "echo \"Error: run tests from root\" && exit 1"
},
"dependencies": {
"@babel/runtime": "^7.17.9",
"@wisdom-components/basictable": "^1.5.25"
}
}
#### 常规使用
<code src="./demos/Basic.tsx">
// 文本/下拉/多选/时间
/**
* @description:
* @params:
* onChange: 需要传入onChange,接收值的变更
*/
import React, { useEffect, useState } from 'react';
import { Input, Select } from 'antd';
import { reportService } from '../../api';
import { returnDefaultValueOrConfigs } from '../utils/utils';
const { Option } = Select;
const { Search } = Input;
const USER_ID = window.globalConfig.userInfo.OID;
const TextSearchComponent = ({ onChange, style, onSearch, placeholder }) => {
return (
<Search
title={placeholder}
style={style}
placeholder={placeholder}
onChange={onChange}
onSearch={onSearch}
/>
);
};
/**
* Data = ['选项1','选项2'...]
*
* @props:
* 正常选项:武汉
* 附带统计数值: 武汉 (20)
*/
const SelectSearchComponent = ({
onChange,
style,
data,
mode,
reportName,
fieldAlias,
configItems,
filterFields,
filterValues,
filterObject,
}) => {
const [value, setValue] = useState('');
const [options, setOptions] = useState([]);
const defaultConfigs = returnDefaultValueOrConfigs(configItems, ['defaultValue']);
const { defaultValue } = defaultConfigs;
const getData = () => {
reportService
.getReportFilterValues({
fieldAlias,
...filterObject,
})
.then((res) => {
if (res.code === 0) {
let _options = res.data
.find((item) => item.fieldAlias === fieldAlias)
.filterValues.filter((item) => item.filterValue);
if (filterValues && filterFields) {
let _filterFields = filterFields.split('|');
let _filterValues = filterValues.split('|');
let _index = _filterFields.findIndex((item) => item === fieldAlias);
if (_index > -1) {
let _needToFilterValues = _filterValues[_index]?.split(',') || [];
_options = _options.filter((item) => _needToFilterValues.includes(item.filterValue));
}
}
setOptions(_options);
}
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
getData();
setValue(defaultValue);
}, []);
return (
<Select
value={value}
style={style}
onChange={(e) => {
onChange(e);
setValue(e);
}}
mode={mode}
defaultValue={mode === 'multiple' && defaultValue ? 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,
filterValues,
filterFields,
filterObject,
}) => {
let _component = '';
switch (type) {
case '文本':
_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}
filterFields={filterFields}
filterValues={filterValues}
filterObject={filterObject}
/>
);
break;
default:
break;
}
return _component;
};
export default ReturnControlComponent;
/*
** 自定义取色板
** create by ChenLong on 2022/8/23
** 功能路径:src\pages\product\ReportsManage\Components\CustomerColorPicker.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
**/
import React from 'react';
import style from './CustomerColorPicker.less';
import { tagColors, tagBackgroundColors } from '../../utils/constant';
import classnames from 'classnames';
const CustomerColorPicker = (props) => {
return (
<div className={style.colorPickerWrapper}>
{tagColors.map((color, index) => (
<div
className={classnames(style.colorCard)}
onClick={() => props.clickColorPicker(tagBackgroundColors[index])}
style={{
color: color,
backgroundColor: tagBackgroundColors[index],
}}
>
A
</div>
))}
</div>
);
};
export default CustomerColorPicker;
@import '~antd/es/style/themes/default.less';
.colorPickerWrapper {
display: flex;
gap: 5px;
width: 330px;
//height: 40px;
padding: 10px;
background: #ffffff;
border: 1px solid rgba(200, 200, 200, 0.85);
border-radius: 4px;
.colorCard {
display: flex;
flex: 0 0 30px;
align-items: center;
justify-content: center;
height: 30px;
font-size: 14px;
&:hover {
font-weight: bold;
font-size: 16px;
box-shadow: #1685ff;
cursor: pointer;
}
}
}
/** @tips: 约定:该控件,获取文件路径字符串或上传了文件(即对应编辑时从接口获取的文件链接和新增时获取的对象),都会将符合要求的对象(上传的文件数据或自行拼接的,必须包含status、type、uid等必要字段)转化为字符串 */
/**
* @description: 合并老版的文件、可预览文件、录音、视频
* @params: 接收参数 renderTo: Recording/Video/File
* @return: {Object} 文件类型返回需要另外处理
* @date: 2021/12/1
* @author: ChenLong
* @待解决问题: 为什么list不直接返回url,而要把file对象变成对象字符串?
*/
/** @tips: 上传业务为:1.通过上传接口,上传文件,获取上传的链接;2.将文件链接存储到服务器,获取存储的地址;3.提交地址 */
/**
* @description: 完成 1.文件名校验;2.编辑界面的文件加载及显示的能力;3.不同类型文件的判断
* @date: 2021/12/2
*/
/**
* @description: 合并图片/可预览图片到文件上传中
* @date: 2021/12/6
*/
/**
* @description: 文件类型单独处理。文件类型返回的是文件对象的字符串,使用JSON.parse解析之后,取url值即可,拼成用逗号分割的字符串即可。这部分修改在入口文件内
* @description: 需要判断值是文件对象的字符串,约定:文件类必须会有 status: 'done'
* @date: 2021/12/8
*/
/** @tips: 裁剪功能在前端框架内无法正常工作,暂不提供裁剪功能 */
// 自定义Form Render组件
import React, { useState, useEffect } from 'react';
import { Upload, Button, Modal, message } from 'antd';
import { UploadOutlined, DownloadOutlined } from '@ant-design/icons';
import './fileUpload.less';
import { downloadFunc, filenameVerification } from '../../utils/utils';
import { uploadFileUrl, downloadFileUrl } from '../../../api/service/workflow';
const videoTypeArray = ['.mp4'];
const audioTypeArray = ['.mp4'];
const fileTypeArray = [];
const imageTypeArray = ['.bmp', '.gif', '.jpeg', 'tiff', '.png', '.svg', '.jpg'];
const FileUpload = ({ value, onChange, schema }) => {
const _isRecordingOrVideo = ['Recording', 'Video', 'Image'].includes(schema.renderTo);
const _isVideo = schema.renderTo === 'Video';
const _isAudio = schema.renderTo === 'Recording';
const _isImage = schema.renderTo === 'Image';
const [previewTitle, setPreviewTitle] = useState('');
const [previewVisible, setPreviewVisible] = useState(false);
const [previewUrl, setPreviewUrl] = useState('');
const [showList, setShowList] = useState('');
const file = value || schema.default;
const option = {
name: 'file',
action: `${window.location.origin}${uploadFileUrl}`,
listType: _isRecordingOrVideo ? 'picture-card' : 'picture',
withCredentials: true,
beforeUpload(file, fileList) {
/** @tips: 解决提交文件中存在特殊字符的问题 */
let _continueUpload = true;
let _msg = {
type: 'success',
content: '上传成功!',
};
fileList.forEach((item) => {
let _msgObject = filenameVerification(item);
if (_msgObject.type === 'error') {
_continueUpload = false;
_msg = {
type: 'error',
content: '上传失败!文件名不符合规则!',
};
}
});
_msg.type === 'error' ? message[_msg.type](_msg.content) : '';
return _continueUpload;
},
onChange: ({ file, fileList, event }) => {
// 检验名字,名字不通过不允许显示
if (filenameVerification(file).type === 'error') return false;
// 返回的链接在file.response内;不设置url,预览图表不可点击
if (file.status === 'done' && file.response.code === 0) {
file.url = `${downloadFileUrl}?filePath=${file.response.data}`;
file.sourcePath = file.response.data;
message.success('上传成功!');
} else if (file.status === 'done' && file.response.code !== 0) {
file.status = 'error';
message.error('上传失败!');
}
onChange((fileList && fileList.length && JSON.stringify(fileList)) || '');
setShowList(JSON.stringify(fileList));
},
onPreview(file) {
if (_isRecordingOrVideo) {
setPreviewVisible(true);
setPreviewUrl(file.url);
}
},
previewFile(file) {},
onDownload(file) {
downloadFunc(file.url, file.name, '_self');
},
};
const handleCancel = () => {
setPreviewVisible(false);
setPreviewTitle('');
};
/**
* @description: 返回文件类型限定值
* @params: {Array} typeArray: Video | Recording | File
* @date: 2021/12/2
* @author: ChenLong
*/
const returnFileTypeString = (type) => {
let _obj = {
Video: videoTypeArray,
Recording: audioTypeArray,
File: fileTypeArray,
Image: imageTypeArray,
};
return _obj[type].join(',');
};
useEffect(() => {
let fileList = [];
(file || '').split(',').forEach((item, index) => {
if (item && filenameVerification({ name: item }, true).type !== 'error') {
// @Tips: 直接过滤掉名字中有异常字符的文件
let _obj = {
uid: index + '_' + Math.random(),
value: item,
name: item.split('\\').reverse()[0],
type: schema.renderTo === 'Image' ? 'image' : 'file',
status: 'done',
url: `${downloadFileUrl}?filePath=${item}`,
sourcePath: item,
};
if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}`;
fileList.push(_obj);
}
});
// onChange(fileList.length && JSON.stringify(fileList) || '');
setShowList(JSON.stringify(fileList));
}, []);
useEffect(() => {
if (value) {
let fileList = [];
(file || '').split(',').forEach((item, index) => {
if (item && filenameVerification({ name: item }, true).type !== 'error') {
// @Tips: 直接过滤掉名字中有异常字符的文件
let _obj = {
uid: index + '_' + Math.random(),
value: item,
name: item.split('\\').reverse()[0],
type: schema.renderTo === 'Image' ? 'image' : 'file',
status: 'done',
url: `${downloadFileUrl}?filePath=${item}`,
sourcePath: item,
};
if (schema.renderTo === 'Image') _obj.thumbUrl = `${downloadFileUrl}?filePath=${item}`;
fileList.push(_obj);
}
});
// onChange(fileList.length && JSON.stringify(fileList) || '');
setShowList(JSON.stringify(fileList));
}
}, [value]);
return (
<>
{/** @tips: 裁剪功能无法正常工作,暂不提供 */}
{/* <ImgCrop beforeCrop={(file) => {
let _returnObj = filenameVerification(file);
if (_returnObj.type === 'error') {
message.error(_returnObj.content);
return false;
}
return schema.renderTo === 'Image';
}} rotate locale={'zh-cn'} modalTitle={'编辑图片'} modalOk={'确定'}
modalCancel={'取消'}>*/}
<Upload
disabled={schema.disabled}
{...option}
fileList={showList ? JSON.parse(showList) : []}
multiple
style={{ width: '100%' }}
className={_isRecordingOrVideo ? 'formUploadVideoOrRecording' : 'formUpload'}
showUploadList={{
showPreviewIcon: _isRecordingOrVideo,
showDownloadIcon: true,
downloadIcon: <DownloadOutlined />,
}}
accept={returnFileTypeString(schema.renderTo)}
>
{!_isRecordingOrVideo ? (
<Button disabled={schema.disabled} icon={<UploadOutlined />}>
Upload
</Button>
) : (
'+ Upload'
)}
</Upload>
{/* </ImgCrop>*/}
<Modal
style={{ width: '30%' }}
bodyStyle={{ textAlign: 'center' }}
visible={previewVisible}
title={previewTitle}
footer={null}
onCancel={handleCancel}
>
{_isVideo ? (
<video width={'100%'} height={'100%'} controls autoPlay src={previewUrl} />
) : (
''
)}
{_isAudio ? <audio controls autoPlay src={previewUrl} /> : ''}
{_isImage ? <img width={'100%'} height={'100%'} src={previewUrl} alt="缩略图" /> : ''}
</Modal>
</>
);
};
export default FileUpload;
@import '~antd/es/style/themes/default.less';
@parse-form-prefix-cls: ~'@{ant-prefix}-parse-form';
.@{parse-form-prefix-cls} {
.formUpload {
width: 100%;
.@{ant-prefix}-upload-list-item {
float: left;
width: 49%;
max-width: 300px; // 增加了最大宽度,防止样式失效导致布局错误的问题
margin-right: 1%;
}
}
.@{ant-prefix}-animate {
}
.formUploadVideoOrRecording {
width: 100%;
.@{ant-prefix}-upload-list-item {
float: left;
width: 99%;
margin-right: 1%;
}
}
}
/*
** 报表的编辑、新增表单
** create by ChenLong on 2022/8/10
** 功能路径:src\pages\product\ReportsManage\ReportEditForm.js
** 菜单参数列表:*变量名*(变量说明,数据类型,是否必填,取值范围)
**/
import React, { useEffect, useState, useContext } from 'react';
import {
Form,
Input,
DatePicker,
InputNumber,
Row,
Col,
Button,
message,
Select,
ConfigProvider,
} from 'antd';
import moment from 'moment';
import { submitReportData } from '../api/service/report';
import FileUpload from './Components/fileUpload/fileUpload';
import { reportService } from '../api';
import { isSelect, returnOptions, returnRows, returnCols } from './utils/utils';
import style from './ReportEditForm.less';
const { Option } = Select;
const { TextArea } = Input;
// 类型
const USER_ID = window.globalConfig.userInfo.OID;
const TEXT_ARRAY = ['文本', '标签'];
const TEXTAREA_ARRAY = ['多行文本'];
const DATE_PICKER_ARRAY = ['日期'];
const DATE_TIME_PICKER_ARRAY = ['日期时刻'];
const DATE_TYPE = ['日期', '日期时刻']; // 用来匹配是否需要转为日期对象;
const NUMBER_ARRAY = ['数值', '数值标签'];
const FILE_ARRAY = ['附件'];
// 形态对应组件
// 对应关系
/**
* @description: 函数描述
* @date: 2022/8/10
* @author: ChenLong
* @params: reportDetails 各个字段的配置列表
* data 与reportDetails对应的值
*/
const ReportEditForm = ({ reportDetails, reportData, onCancel, reportName, modalType }) => {
// if (!reportData || Object.keys(reportData).length === 0) return <>未传递表单数据</>;
const [fileAlias, setFileAlias] = useState([]); // 附件需要单独处理提交的数据
const [form] = Form.useForm();
const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
const prefixCls = getPrefixCls();
/* const formItemLayout = {
labelCol: {
span: 8,
},
wrapperCol: {
span: 16,
},
};*/
// 数值类的后端会处理再返回,故无序处理精度问题
const handleDate = (reportDetails, data) => {
let _data = { ...data };
reportDetails.forEach((item) => {
if (DATE_TYPE.includes(item.type)) {
_data[item.fieldAlias] = data[item.fieldAlias] ? moment(data[item.fieldAlias]) : moment();
}
});
return _data;
};
const componentMap = (config) => {
if (DATE_TIME_PICKER_ARRAY.includes(config.type)) {
return <DatePicker showTime readonly={config.isReadOnly} />;
} else if (DATE_PICKER_ARRAY.includes(config.type)) {
return <DatePicker disabled={config.isReadOnly} />;
} else if (NUMBER_ARRAY.includes(config.type)) {
return <InputNumber disabled={config.isReadOnly} />;
} else if (FILE_ARRAY.includes(config.type)) {
return <FileUpload schema={{ renderTo: 'File' }} disabled={config.isReadOnly} />;
} else if (TEXTAREA_ARRAY.includes(config.type)) {
let _rows = returnRows(config.configItems);
return <TextArea rows={_rows} disabled={config.isReadOnly} />;
} else {
if (isSelect(config.configItems)) {
let options = returnOptions(config.configItems);
if (options) {
return (
<Select disabled={config.isReadOnly}>
{options.map((item) => (
<Option value={item}>{item}</Option>
))}
</Select>
);
}
}
return <Input disabled={config.isReadOnly} />;
}
};
const submitReportForm = () => {
form.validateFields().then((values) => {
let _data = values;
let final = [];
Object.keys(_data).forEach((key) => {
let value = reportData[key];
let _value = _data[key];
if (moment.isMoment(_data[key])) {
_value = moment(_data[key]).format('YYYY-MM-DD HH:mm:ss');
}
if (value !== _value) {
if (fileAlias.includes(key)) {
_value = _value
? JSON.parse(_value)
.reduce((final, curr) => {
final.push(curr.sourcePath);
return final;
}, [])
.join(',')
: '';
}
let _finalData = {
fieldAlias: key,
fieldValue: _value,
};
if (modalType === '编辑') {
_finalData.key = reportData.Key;
}
final.push(_finalData);
}
});
if (modalType === '新增') {
reportService
.addReportData({
reportName: reportName,
userId: USER_ID,
reportDatas: final,
})
.then((res) => {
if (res.code === 0) {
message.success('保存成功!');
onCancel();
} else if (res.code === -1) {
message.error(res.msg);
} else if (res.code === -2) {
message.error('系统故障,请找管理员查看故障!');
}
});
}
if (modalType === '编辑') {
submitReportData(
{},
{
editDatas: final,
reportName: reportName,
userId: USER_ID,
},
).then((res) => {
if (res.code === 0) {
message.success('保存成功!');
onCancel();
} else if (res.code === -1) {
message.error(res.msg);
} else if (res.code === -2) {
message.error('系统故障,请找管理员查看故障!');
}
});
}
});
};
useEffect(() => {
if (reportDetails && reportDetails.length) {
let _fileAlias = [...fileAlias];
reportDetails.forEach((item) => {
if (item.type === '附件') _fileAlias.push(item.fieldAlias);
});
setFileAlias(_fileAlias);
}
}, [reportDetails]);
useEffect(() => {
if (reportData && Object.keys(reportData).length)
form.setFieldsValue(handleDate(reportDetails, reportData));
}, [reportData]);
return (
<div className={style.reportEditForm} style={{ position: 'relative' }}>
<div>
<Form form={form}>
<Row style={{ overflowY: 'scroll', maxHeight: 'calc(100vh - 300px)' }}>
{reportDetails &&
reportDetails
.filter((config) => {
if (modalType === '新增' && config.isReadOnly) return false;
return config;
})
.map((config) => {
// return <Col span={returnCols(config.configItems) * 8} key={config.fieldAlias}>
return (
<div
style={{ width: `${returnCols(config.configItems) * 33.3}%` }}
key={config.fieldAlias}
>
<Form.Item
label={config.fieldAlias}
name={config.fieldAlias}
rules={[
{
required: config.isRequired,
message: `${config.fieldAlias}必填`,
},
]}
>
{componentMap(config)}
</Form.Item>
</div>
);
})}
</Row>
<Row>
<Col span={24} style={{ textAlign: 'right' }}>
{/*<Form.Item style={{textAlign:'right'}}>*/}
<Button
style={{ position: 'sticky', bottom: 0 }}
type={'primary'}
onClick={submitReportForm}
>
提交
</Button>
{/*</Form.Item>*/}
</Col>
</Row>
</Form>
</div>
</div>
);
};
export default ReportEditForm;
@import '~antd/es/style/themes/default.less';
.reportEditForm {
:global {
.@{ant-prefix}-form-item-label {
width: 120px !important;
}
input[disabled] {
background-color: rgb(250, 250, 250);
cursor: default;
}
// 多行文本框
.@{ant-prefix}-input[disabled] {
color: rgba(0, 0, 0, 0.85);
background-color: rgb(250, 250, 250);
border-color: #d9d9d9;
box-shadow: none;
cursor: default;
opacity: 1;
}
// 时间选择器的disabled样式
.@{ant-prefix}-picker-disabled {
color: rgba(0, 0, 0, 0.85);
background-color: rgb(250, 250, 250);
cursor: default;
& + span {
cursor: default;
}
}
// radio的disabled样式
.@{ant-prefix}-radio-disabled {
cursor: default;
& + span {
cursor: default;
}
.@{ant-prefix}-radio-inner {
cursor: default;
}
}
// 下拉选已选的disabled样式
.@{ant-prefix}-cascader-picker-disabled {
color: rgba(0, 0, 0, 0.85);
background-color: rgb(250, 250, 250);
cursor: default;
}
// 按钮的disabled样式
.@{ant-prefix}-btn[disabled] {
text-shadow: none;
background: #ffffff;
border-color: #d9d9d9;
box-shadow: none;
cursor: default;
&:hover,
&:focus,
&:active {
color: rgba(0, 0, 0, 0.25);
text-shadow: none;
background: #ffffff;
border-color: #d9d9d9;
box-shadow: none;
}
}
// 多选下的tag的disabled样式
.@{ant-prefix}-select-disabled.@{ant-prefix}-select-multiple {
.@{ant-prefix}-select-selection-item {
color: #bfbfbf;
border-color: #d9d9d9;
cursor: default;
}
}
.@{ant-prefix}-select-disabled.@{ant-prefix}-select:not(.@{ant-prefix}-select-customize-input) {
.@{ant-prefix}-select-selector input {
cursor: default;
}
}
// 时间选择框
.@{ant-prefix}-picker-input > input[disabled] {
color: rgba(0, 0, 0, 0.85);
}
}
}
@import '~antd/es/style/themes/default.less';
.reportsDataSourceSetting {
height: 100%;
overflow: hidden;
.contentWrapper {
display: flex;
flex-direction: column;
height: calc(100% - 16px);
margin: 8px;
@media screen and (min-width: 1680px) {
.content {
grid-template-columns: repeat(5, 1fr);
}
}
@media screen and (max-width: 1680px) {
.content {
grid-template-columns: repeat(4, 1fr);
}
}
@media screen and (max-width: 1320px) {
.content {
grid-template-columns: repeat(3, 1fr);
}
}
@media screen and (max-width: 960px) {
.content {
grid-template-columns: repeat(2, 1fr);
}
}
.controlRow {
display: flex;
flex-direction: column;
margin-bottom: 8px;
padding: 8px;
background: #ffffff;
:global {
.@{ant-prefix}-form-item {
margin-bottom: 0;
}
}
}
.content {
display: grid;
grid-gap: 10px;
padding-bottom: 8px;
overflow: scroll;
.card {
height: 198px;
.cardInfo {
padding-left: 48px;
.cardInfoItem {
margin-bottom: 4px;
color: rgb(100, 100, 100, 0.65);
.item {
color: rgba(58, 58, 58, 0.55);
font-weight: bold;
}
.blue {
color: rgba(23, 130, 252, 0.65);
}
.ellipsis {
display: inline-block;
max-width: 120px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: top;
}
}
}
}
}
}
}
@import '~antd/es/style/themes/default.less';
.lackParams {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.reportManage {
display: flex;
flex-direction: column;
height: 100%;
padding: 8px;
.contentWrapper {
display: flex;
flex-direction: column;
height: 100%;
.controlRow {
display: flex;
flex-direction: row;
margin-bottom: 4px;
padding: 6px;
background: #ffffff;
border-radius: 4px;
}
.tableContent {
flex: 1;
padding: 6px;
background: #ffffff;
.handleColumnWrapper {
display: flex;
justify-content: space-around;
.editButton {
cursor: pointer;
&:hover {
color: rgb(24, 144, 255);
}
}
.deleteButton {
color: rgb(255, 0, 0);
cursor: pointer;
&:hover {
//color: rgb(24, 144, 255);
}
}
}
.spinWrapper {
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 60vh;
}
:global {
.@{ant-prefix}-table-container {
height: 100%;
& > .@{ant-prefix}-table-body {
border-right: 1px solid #dbe7fb;
border-bottom: 1px solid #dbe7fb;
}
.@{ant-prefix}-table-body {
flex: 1;
}
.@{ant-prefix}-table-summary > table > tfoot > tr > td {
border-right: none;
}
.@{ant-prefix}-table-summary > table > tfoot > tr:not(:last-child) > td {
border-bottom: none;
}
.@{ant-prefix}-table-summary > table > tfoot > tr:last-child > td {
border-bottom: 1px solid #dbe7fb;
}
}
.@{ant-prefix}-basic-table .@{ant-prefix}-pagination {
border-top: none;
}
}
}
}
.link {
cursor: pointer;
&:hover {
//color: #1685FF;
font-weight: bold;
text-decoration: underline;
}
}
:global {
.@{ant-prefix}-form-item {
margin-bottom: 0 !important;
}
}
.prefixOrSuffix {
color: rgba(0, 0, 0, 0.65);
font-size: 10px;
}
:global {
::-webkit-scrollbar,
*::-webkit-scrollbar {
width: 0px;
height: 6px;
}
::-webkit-scrollbar-track,
*::-webkit-scrollbar-track {
background: #f2f2f2;
border-radius: 10px;
}
::-webkit-scrollbar-thumb,
*::-webkit-scrollbar-thumb {
background: #dcdcdc;
border-radius: 5px;
}
}
}
import React from 'react';
import ReportsManage from './ReportsManage';
const ReportsPermissionDelete = (props) => <ReportsManage {...props} state="delete" />;
export default ReportsPermissionDelete;
import React from 'react';
import ReportsManage from './ReportsManage';
const ReportsPermissionScan = (props) => <ReportsManage {...props} state="scan" />;
export default ReportsPermissionScan;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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