Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wisdom-components
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ReactWeb5
wisdom-components
Commits
437dd7ca
Commit
437dd7ca
authored
Sep 05, 2022
by
陈龙
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 新增大量功能
parent
34c8f109
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1239 additions
and
402 deletions
+1239
-402
CustomerColorPicker.js
...age/Components/customerColorPicker/CustomerColorPicker.js
+30
-0
CustomerColorPicker.less
...e/Components/customerColorPicker/CustomerColorPicker.less
+26
-0
fileUpload.js
...ort/src/ReportsManage/Components/fileUpload/fileUpload.js
+222
-0
fileUpload.less
...t/src/ReportsManage/Components/fileUpload/fileUpload.less
+25
-0
ReportEditForm.js
...omponents/BasicReport/src/ReportsManage/ReportEditForm.js
+121
-58
ReportsManage.js
...components/BasicReport/src/ReportsManage/ReportsManage.js
+348
-168
ReportsSetting.js
...omponents/BasicReport/src/ReportsManage/ReportsSetting.js
+315
-164
constant.js
...omponents/BasicReport/src/ReportsManage/utils/constant.js
+23
-0
handlers.js
...omponents/BasicReport/src/ReportsManage/utils/handlers.js
+22
-12
utils.js
...e-components/BasicReport/src/ReportsManage/utils/utils.js
+42
-0
report.js
...ges/base-components/BasicReport/src/api/service/report.js
+65
-0
No files found.
packages/base-components/BasicReport/src/ReportsManage/Components/customerColorPicker/CustomerColorPicker.js
0 → 100644
View file @
437dd7ca
/*
** 自定义取色板
** 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
;
packages/base-components/BasicReport/src/ReportsManage/Components/customerColorPicker/CustomerColorPicker.less
0 → 100644
View file @
437dd7ca
@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;
}
}
}
packages/base-components/BasicReport/src/ReportsManage/Components/fileUpload/fileUpload.js
0 → 100644
View file @
437dd7ca
/** @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
(()
=>
{
debugger
;
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;
packages/base-components/BasicReport/src/ReportsManage/Components/fileUpload/fileUpload.less
0 → 100644
View file @
437dd7ca
@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%;
}
}
}
packages/base-components/BasicReport/src/ReportsManage/ReportEditForm.js
View file @
437dd7ca
...
...
@@ -8,11 +8,15 @@ 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
FileUpload
from
'./Components/fileUpload/fileUpload'
;
import
{
reportService
}
from
'../api'
;
// 类型
const
USER_ID
=
window
.
globalConfig
.
userInfo
.
OID
;
const
DATE_PICKER_ARRAY
=
[
'日期'
];
const
DATE_TIME_PICKER_ARRAY
=
[
'日期时刻'
];
const
DATE_TYPE
=
[
'日期'
,
'日期时刻'
];
// 用来匹配是否需要转为日期对象;
const
NUMBER_ARRAY
=
[
'数值'
,
'金额'
];
const
FILE_ARRAY
=
[
'附件'
];
// 形态对应组件
// 对应关系
...
...
@@ -24,8 +28,9 @@ const NUMBER_ARRAY = ['数值', '金额'];
* @params: reportDetails 各个字段的配置列表
* data 与reportDetails对应的值
*/
const
ReportEditForm
=
({
reportDetails
,
reportData
,
onCancel
,
reportName
})
=>
{
if
(
!
reportData
||
Object
.
keys
(
reportData
).
length
===
0
)
return
<>
未传递表单数据
<
/>
;
const
ReportEditForm
=
({
reportDetails
,
reportData
,
onCancel
,
reportName
,
modalType
})
=>
{
// if (!reportData || Object.keys(reportData).length === 0) return <>未传递表单数据</>;
const
[
fileAlias
,
setFileAlias
]
=
useState
([]);
// 附件需要单独处理提交的数据
const
[
form
]
=
Form
.
useForm
();
const
formItemLayout
=
{
labelCol
:
{
...
...
@@ -52,77 +57,135 @@ const ReportEditForm = ({ reportDetails, reportData, onCancel, reportName }) =>
return
<
DatePicker
/>
;
}
else
if
(
NUMBER_ARRAY
.
includes
(
config
.
type
))
{
return
<
InputNumber
/>
;
}
else
if
(
FILE_ARRAY
.
includes
(
config
.
type
))
{
return
<
FileUpload
schema
=
{{
renderTo
:
'File'
}}
/>
;
}
else
{
return
<
Input
/>
;
}
};
const
submitReportForm
=
()
=>
{
let
_data
=
form
.
getFieldsValue
();
console
.
log
(
_data
);
// {
// "key": "string",
// "fieldName": "string",
// "fieldValue": "string"
// }
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'
);
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
(
value
!==
_value
)
{
final
.
push
({
key
:
reportData
.
Key
,
fieldName
:
key
,
fieldValue
:
_value
,
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
(
'系统故障,请找管理员查看故障!'
);
}
});
}
});
console
.
log
(
final
);
// reportService.updateReportData()
submitReportData
(
{
reportName
:
reportName
,
userId
:
window
.
globalConfig
.
userInfo
.
OID
,
},
final
,
).
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
message
.
success
(
'保存成功!'
);
onCancel
();
}
});
};
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
>
<
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
>
);
})}
<
/Row
>
<
Row
>
<
Col
span
=
{
24
}
style
=
{{
textAlign
:
'right'
}}
>
{
/*<Form.Item style={{textAlign:'right'}}>*/
}
<
Button
type
=
{
'primary'
}
onClick
=
{
submitReportForm
}
>
提交
<
/Button
>
{
/*</Form.Item>*/
}
<
/Col
>
<
/Row
>
<
/Form
>
<
div
style
=
{{
position
:
'relative'
}}
>
<
div
>
<
Form
{...
formItemLayout
}
form
=
{
form
}
>
<
Row
style
=
{{
overflowY
:
'scroll'
,
maxHeight
:
'calc(100vh - 300px)'
}}
>
{
reportDetails
&&
reportDetails
.
map
((
config
)
=>
{
return
(
<
Col
span
=
{
8
}
key
=
{
config
.
fieldAlias
}
>
<
Form
.
Item
label
=
{
config
.
fieldAlias
}
name
=
{
config
.
fieldAlias
}
rules
=
{[
{
required
:
config
.
isRequired
,
message
:
`
${
config
.
fieldAlias
}
必填`
,
},
]}
>
{
componentMap
(
config
)}
<
/Form.Item
>
<
/Col
>
);
})}
<
/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
>
);
};
...
...
packages/base-components/BasicReport/src/ReportsManage/ReportsManage.js
View file @
437dd7ca
...
...
@@ -12,62 +12,47 @@
* @params: <ReportManage
* params={{reportName,pageSize,filterFields,filterValues,state,customerState}}>
*
*
*
*
* reportName: 报表名称;
* pageSize: 按需配置,默认加载100;
* filterFields:
*
* ***************filterFields/filterValues多用于以组件的形式嵌入,将需要过滤的条件传入********************
*
*
* 需要默认加载的过滤条件的field,英文逗号分割,与filterValues一一对应;
* filterFields: 需要默认加载的过滤条件的field,英文逗号分割,与filterValues一一对应;
* filterValues:
*
*
*
* 需要默认加载的过滤条件的value,英文逗号分割,与filterFields一一对应;
* state: delete|edit|scan 各种权限;
*
*
*
* *************************************************************************************************
*
* customerState: ['filters','sortBtn','exportBtn','editBtn','deleteBtn','pagination'];
* state: delete|edit|scan 各种权限;
* customerState:
* ['filters','sortBtn','exportBtn','editBtn','deleteBtn','pagination'];
* sortFields:
* '排序字段1,排序字段2,排序字段3'
*
* ---------------------------------------权限过滤-----------------------------------------
*
* permissionType: 部门|站点|用户
* permissionField: 【字段名】
*
*
* sortFields: '排序字段1,排序字段2,排序字段3'
* ---------------------------------------------------------------------------------------
* @config:
* 【数值】 [prefix]_d%|0.00|_d%[suffix]|金额 = 前缀|精度|后缀|金额类的数据(千分位),可分别设置。
* 【标签】 split=,
*
*
* 分隔符。
* 【标签】 split=, 分隔符。
*
* 【功能】 功能配置框内,配置需要跳转功能所需参数,type、url是必须功能,需要type判断类型,需要通过url去解析加载组件。
* @type:
* 【文本】普通文本
* 【数值】数值类型的文本
* 【标签】文本渲染成标签,具有不同颜色;
* 【功能】“功能”会在当前页内去展示,会卸载掉列表页,加载功能组件。配置 type
* +
*
*
* url + 自定义字段 的配置项,自行解析加载即可;
* -------------------- 待需求提出后开发
* -----------------
*
*
* 【功能】“功能”会在当前页内去展示,会卸载掉列表页,加载功能组件。配置 type +
* url + 自定义字段 的配置项,自行解析加载即可;
* -------------------- 待需求提出后开发 -----------------
*
* 【链接】内链外链,点击可跳转;配置规则:配置链接即可;
*
* 【弹窗】modal弹窗弹出,弹窗内的具体业务自行配置;配置规则:[function_name];[...params];
*
*
*
* 【弹窗】modal弹窗弹出,弹窗内的具体业务自行配置;配置规则:[function_name];[...params];
*
* ------------------------------------------------------
* 【附件】
* @table:
* 表头:表头需要支持多级表头、合并;
* 列:列支持设置筛选;
...
...
@@ -75,15 +60,9 @@
* @control:
* 固定筛选:拥有固定筛选框,根据配置显示可搜索字段;
*
*
*
*
* 可配置筛选框:根据字段配置,将字段设置成筛选条件,枚举出该字段所有值,提供用户进行选择,然后进行筛选;筛选框具体形态可根据配置字段来渲染;
* 导出功能:各类导出功能按钮;
*
*
*
*
* 时间筛选框:单表唯一;需要变更,支持多时间参数的筛选
* @state: 参考台账权限 delete 全部权限
* edit 除删除外的权限
...
...
@@ -103,13 +82,20 @@ import {
Dropdown
,
Menu
,
Spin
,
Popconfirm
,
Tooltip
,
}
from
'antd'
;
import
{
SortAscendingOutlined
,
MinusCircleOutlined
,
ExportOutlined
,
FormOutlined
,
PlusOutlined
,
DeleteOutlined
,
QuestionCircleOutlined
,
HeartTwoTone
,
HeartOutlined
,
DownOutlined
,
}
from
'@ant-design/icons'
;
import
BasicTable
from
'@wisdom-components/basictable'
;
import
ReturnControlComponent
from
'./Components/Control'
;
...
...
@@ -135,6 +121,7 @@ import {
import
{
hasMoney
,
isArray
,
isNumber
,
isString
,
returnHandledNumber
}
from
'./utils/utils'
;
import
{
connect
}
from
'react-redux'
;
import
ReportEditForm
from
'./ReportEditForm'
;
import
{
exportJPG
}
from
'../api/service/report'
;
const
ControlsType
=
[
'下拉'
,
'多选'
,
'日期'
];
const
fieldSplitStr
=
'-'
;
// fieldGroup用来分割
...
...
@@ -144,6 +131,7 @@ const initDateModel = 'all';
let
timer
=
null
;
const
PERMISSION
=
{
delete
:
[
'addBtn'
,
'filters'
,
'pagination'
,
// 操作条按钮
...
...
@@ -154,6 +142,7 @@ const PERMISSION = {
'deleteBtn'
,
],
edit
:
[
'addBtn'
,
'filters'
,
'pagination'
,
'sortBtn'
,
...
...
@@ -161,11 +150,22 @@ const PERMISSION = {
// 操作列
'editBtn'
,
],
scan
:
[
'filters'
,
'pagination'
],
scan
:
[
'filters'
,
'pagination'
,
'sortBtn'
],
};
const
USER_ID
=
window
.
globalConfig
.
userInfo
.
OID
;
const
MODEL
=
[
'all'
,
'year'
,
'quarter'
,
'month'
,
'week'
,
'day'
];
const
ReportsManage
=
(
props
)
=>
{
const
{
reportName
,
pageSize
,
filterFields
,
filterValues
,
state
,
customerState
,
sortFields
}
=
props
.
params
;
const
{
reportName
,
pageSize
,
filterFields
,
filterValues
,
state
,
customerState
,
sortFields
,
permissionType
,
permissionField
,
}
=
props
.
params
;
const
permission
=
customerState
&&
isArray
(
customerState
)
?
customerState
:
PERMISSION
[
state
||
'delete'
];
const
tableWrapperRef
=
useRef
();
...
...
@@ -174,9 +174,12 @@ const ReportsManage = (props) => {
return
(
<
div
className
=
{
style
.
lackParams
}
>
未配置
reportName
,请完善配置并重新登陆后查看页面!
<
/div
>
);
const
[
isInit
,
setIsInit
]
=
useState
(
true
);
const
[
firstToGetData
,
setFirstToGetData
]
=
useState
(
false
);
const
[
tableStruct
,
setTableStruct
]
=
useState
([]);
// 临时使用,看后续是否需要保留
const
[
columns
,
setColumns
]
=
useState
([]);
// 表头设置
const
[
tableData
,
setTableData
]
=
useState
([]);
// 表数据
const
[
reportConfigs
,
setReportConfigs
]
=
useState
([]);
// 表设置
const
[
pagination
,
setPagination
]
=
useState
({
current
:
1
,
total
:
0
,
...
...
@@ -191,14 +194,14 @@ const ReportsManage = (props) => {
_pagination
.
current
=
current
;
_pagination
.
pageSize
=
size
;
setPagination
(
_pagination
);
getData
(
false
,
_pagination
);
getData
(
_pagination
);
},
onChange
:
(
current
,
size
)
=>
{
let
_pagination
=
{
...
pagination
};
_pagination
.
current
=
current
;
_pagination
.
pageSize
=
size
;
setPagination
(
_pagination
);
getData
(
false
,
_pagination
);
getData
(
_pagination
);
},
});
const
[
controls
,
setControls
]
=
useState
([]);
// 用来存储操作控件
...
...
@@ -240,9 +243,10 @@ const ReportsManage = (props) => {
// const [detailsComponent, setDetailsComponent] = useState(<></>); // 详情组件
const
[
detailsComponentVisible
,
setDetailsComponentVisible
]
=
useState
(
false
);
// 是否显示详情组件
const
[
editComponentVisible
,
setEditComponentVisible
]
=
useState
(
false
);
// 是否显示编辑组件
const
[
modalType
,
setModalType
]
=
useState
(
''
);
// const [editComponentVisible, setEditComponentVisible] = useState(false); // 是否显示编辑组件
const
[
currentData
,
setCurrentData
]
=
useState
({});
// 设置当前编辑数据
const
[
s
roter
,
setSorter
]
=
useState
({});
const
[
s
orterObject
,
setSorterObject
]
=
useState
({});
const
[
detailConfig
,
setDetailConfig
]
=
useState
({
url
:
''
,
type
:
''
,
params
:
{}
});
const
[
controlsHeight
,
setControlsHeight
]
=
useState
(
44
);
const
menu
=
()
=>
{
...
...
@@ -275,6 +279,20 @@ const ReportsManage = (props) => {
),
key
:
'exportExcel'
,
},
{
label
:
(
<
Button
size
=
"middle"
loading
=
{
exportLoading
}
type
=
"text"
onClick
=
{()
=>
exportImage
()}
icon
=
{
<
ExportOutlined
/>
}
>
导出
JPG
<
/Button
>
),
key
:
'excelPdf'
,
},
];
return
<
Menu
items
=
{
_item
}
/>
;
};
...
...
@@ -315,8 +333,38 @@ const ReportsManage = (props) => {
setExportLoading
(
false
);
});
};
const
exportImage
=
()
=>
{
exportJPG
(
{
responseType
:
'blob'
},
{
reportName
,
pageIndex
:
1
,
pageSize
:
10
,
sortFields
:
''
,
content
:
''
,
filters
:
[
{
fieldAlias
:
''
,
fieldValue
:
''
,
},
],
},
).
then
((
res
)
=>
{
if
(
res
&&
res
.
code
===
-
1
)
return
message
.
error
(
res
.
msg
);
const
url
=
window
.
URL
.
createObjectURL
(
new
Blob
([
res
],
{
type
:
'application/zip;charset=UTF-8'
}),
);
const
a
=
document
.
createElement
(
'a'
);
a
.
href
=
url
;
a
.
target
=
'_blank'
;
a
.
download
=
`
${
reportName
}${
moment
().
format
(
'YYYY-MM-DD-HH-mm-ss'
).
replaceAll
(
'-'
,
''
)}
.zip`
;
a
.
click
();
a
.
remove
();
setExportLoading
(
false
);
});
};
const
searchData
=
(
e
)
=>
{
getData
(
false
,
pagination
);
getData
(
pagination
);
};
const
controlSelectChange
=
(
fieldAlias
,
e
)
=>
{
let
_filterArray
=
{
...
filterObject
};
...
...
@@ -326,9 +374,13 @@ const ReportsManage = (props) => {
const
searchInputChange
=
(
e
)
=>
{
setSearchContent
(
e
.
target
.
value
);
};
const
setConfig
=
(
config
,
summary
,
data
)
=>
{
/* const setConfig = (config, summary) => {
getControlsBarConfig(config);
getTableSummaryConfig(config, summary);
getTableLevel(config);
};*/
const
setConfig
=
(
config
)
=>
{
getControlsBarConfig
(
config
);
getTableSummaryConfig
(
config
,
summary
);
getTableLevel
(
config
);
};
const
addFilterAndSearchParams
=
(
data
)
=>
{
...
...
@@ -373,6 +425,17 @@ const ReportsManage = (props) => {
});
});
}
// 表格上的自定义排序的按钮
if
(
sorterObject
&&
sorterObject
.
order
)
{
_data
.
sortFields
=
`
${
sorterObject
.
columnKey
}
${
sorterObject
.
order
===
'ascend'
?
'asc'
:
'desc'
}
`
;
}
// 增加权限过滤的参数
if
(
permissionType
&&
permissionField
)
{
_data
.
filterType
=
permissionType
;
_data
.
filterField
=
permissionField
;
}
// 并入 _data
if
(
_filters
.
length
)
_data
.
filters
=
_filters
;
return
_data
;
...
...
@@ -426,7 +489,7 @@ const ReportsManage = (props) => {
});
return
_merge
;
};
const
getData
=
(
isInit
,
pagination
)
=>
{
const
getData
=
(
pagination
)
=>
{
setTableLoading
(
true
);
const
{
pageSize
,
current
}
=
pagination
;
// 搜索条件附加到params
...
...
@@ -434,6 +497,7 @@ const ReportsManage = (props) => {
reportName
:
reportName
,
pageIndex
:
current
,
pageSize
:
pageSize
,
userId
:
USER_ID
,
});
// sortFields
reportService
...
...
@@ -444,8 +508,9 @@ const ReportsManage = (props) => {
let
_statisticalValues
=
res
.
data
.
statisticalValues
;
let
_tableData
=
res
.
data
.
data
.
list
;
let
_sortString
=
res
.
data
.
sortString
;
if
(
isInit
)
{
setConfig
(
_reportDetails
,
_statisticalValues
,
_tableData
);
if
(
isInit
||
!
summaryArray
.
length
)
{
getTableSummaryConfig
(
_reportDetails
,
_statisticalValues
);
setIsInit
(
false
);
}
getTableHeaderConfig
(
_reportDetails
,
_tableData
);
let
_pagination
=
{
...
pagination
};
...
...
@@ -471,6 +536,7 @@ const ReportsManage = (props) => {
setPagination
(
_pagination
);
setTableData
([]);
}
if
(
isInit
)
setIsInit
(
false
);
setTableLoading
(
false
);
})
.
catch
((
err
)
=>
{
...
...
@@ -478,6 +544,17 @@ const ReportsManage = (props) => {
setTableLoading
(
false
);
});
};
const
getConfigs
=
()
=>
{
reportService
.
getReportDetails
({
reportName
}).
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
setReportConfigs
(
res
.
data
);
setConfig
(
res
.
data
);
setColumns
(
returnColumn
(
res
.
data
));
setTableStruct
(
res
.
data
);
setFirstToGetData
(
true
);
}
});
};
/** @description: 在配置项中,isFilter: true 用来渲染控制框;filterRule: 下拉/文本/多选 */
const
getControlsBarConfig
=
(
config
)
=>
{
let
_data
=
config
.
filter
((
item
)
=>
item
.
isFilter
);
...
...
@@ -488,11 +565,12 @@ const ReportsManage = (props) => {
setSearchPlaceholder
(
_searchPlaceholder
);
let
_controls
=
_data
.
filter
((
item
)
=>
ControlsType
.
includes
(
item
.
filterRule
));
setControls
(
_controls
);
handleDate
(
_controls
);
handleControls
(
_controls
);
// 处理控制条,设定默认值
handleDate
(
_controls
);
// 处理日期, 设定默认值
};
const
getTableHeaderConfig
=
(
config
,
data
)
=>
{
setTableStruct
(
config
);
setColumns
(
returnColumn
(
config
,
data
));
//
setTableStruct(config);
//
setColumns(returnColumn(config, data));
setAllSortFields
(
returnSortFields
(
config
));
};
const
getTableSummaryConfig
=
(
config
,
summary
)
=>
{
...
...
@@ -601,7 +679,7 @@ const ReportsManage = (props) => {
}
let
_tempObj
=
{};
let
_fieldAliasArray
=
handleDataToGetRowSpanArray
(
_config
,
data
)
;
// 需要向下合并的字段
let
_fieldAliasArray
=
data
?
handleDataToGetRowSpanArray
(
_config
,
data
)
:
false
;
// 需要向下合并的字段
_config
.
forEach
((
item
)
=>
{
let
_item
=
{
title
:
item
.
fieldAlias
,
...
...
@@ -612,7 +690,7 @@ const ReportsManage = (props) => {
// console.log('Record: ', record); // record是这条记录,index是rowIndex
// 1. 如果该字段是需要向下合并的,则进入判断
let
_obj
=
{};
if
(
_fieldAliasArray
[
item
.
fieldAlias
])
{
if
(
_fieldAliasArray
&&
_fieldAliasArray
[
item
.
fieldAlias
])
{
_obj
.
rowSpan
=
_fieldAliasArray
[
item
.
fieldAlias
][
rowIndex
];
}
return
_obj
;
...
...
@@ -639,7 +717,7 @@ const ReportsManage = (props) => {
return
mapHandleType
(
item
.
type
)(
item
,
value
||
''
,
record
,
...
rest
);
},
};
_item
.
width
=
item
.
columnWidth
||
200
;
// 列宽,不设置时默认给200;
_item
.
width
=
(
!
isNaN
(
Number
(
item
.
columnWidth
))
&&
item
.
columnWidth
)
||
200
;
// 列宽,不设置时默认给200;
if
(
item
.
fixedColumn
)
_item
.
fixed
=
item
.
fixedColumn
;
// 固定位置
_item
.
align
=
item
.
alignType
||
'left'
;
// 单元格内对齐方式
let
_keyArray
=
(
item
.
fieldGroup
||
item
.
fieldAlias
||
item
.
fieldName
).
split
(
fieldSplitStr
);
...
...
@@ -682,26 +760,68 @@ const ReportsManage = (props) => {
render
:
(
text
,
record
)
=>
{
return
(
<
Space
className
=
{
style
.
handleColumnWrapper
}
>
{
record
.
IsAllow
?
(
<
Popconfirm
placement
=
"topRight"
title
=
{
'确认取消关注吗'
}
icon
=
{
<
QuestionCircleOutlined
/>
}
onConfirm
=
{()
=>
focusProject
(
record
)}
>
<
Tooltip
title
=
{
'点击取消关注'
}
>
<
HeartTwoTone
twoToneColor
=
"#eb2f96"
/>
<
/Tooltip
>
<
/Popconfirm
>
)
:
(
<
Popconfirm
placement
=
"topRight"
title
=
{
'确认关注项目吗'
}
icon
=
{
<
QuestionCircleOutlined
/>
}
onConfirm
=
{()
=>
focusProject
(
record
)}
>
<
Tooltip
title
=
{
'点击添加关注'
}
>
<
HeartOutlined
/>
<
/Tooltip
>
<
/Popconfirm
>
)}
{
permission
.
includes
(
'editBtn'
)
?
(
<
FormOutlined
className
=
{
style
.
editButton
}
onClick
=
{()
=>
{
setEditComponentVisible
(
true
);
// setEditComponentVisible(true);
setModalType
(
'编辑'
);
setCurrentData
(
record
);
}}
/
>
)
:
(
''
)}
{
/* {
permission.includes('deleteBtn') ?
<DeleteOutlined disabled className={style.deleteButton} onClick={() => {
Modal.confirm({
content: '你确定要删除改数据吗?',
onOK: () => message.error('您无法删除数据!'),
});
}} /> : ''
}*/
}
{
permission
.
includes
(
'deleteBtn'
)
?
(
<
DeleteOutlined
disabled
className
=
{
style
.
deleteButton
}
onClick
=
{()
=>
{
Modal
.
confirm
({
content
:
'你确定要删除该数据吗?'
,
onOk
:
()
=>
{
reportService
.
delReportData
({
reportName
:
reportName
,
userId
:
USER_ID
,
key
:
record
.
Key
,
})
.
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
message
.
success
(
'删除成功!'
);
getData
(
pagination
);
}
});
},
});
}}
/
>
)
:
(
''
)}
<
/Space
>
);
},
...
...
@@ -773,15 +893,31 @@ const ReportsManage = (props) => {
}
});
};
/** @description: 判断是否存在【时间】类型的选择,并返回组件 */
/** @description: 判断是否存在【时间】类型的选择,并返回组件;并记录默认值 */
const
handleControls
=
(
controls
)
=>
{
// 过滤出非日期的字段,存储默认值
let
_controls
=
controls
.
filter
((
item
)
=>
item
.
type
!==
'日期'
);
_controls
.
forEach
((
item
)
=>
{
let
_configItems
=
item
.
configItems
.
split
(
'|'
);
_configItems
.
forEach
((
str
)
=>
{
if
(
str
.
includes
(
'defaultValue='
))
{
controlSelectChange
(
item
.
fieldAlias
,
str
.
replace
(
'defaultValue='
,
''
));
}
});
});
};
const
handleDate
=
(
obj
)
=>
{
let
_typeObj
=
obj
.
find
((
item
)
=>
item
.
filterRule
===
'日期'
);
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
_defaultModel
=
_configItems
.
find
((
item
)
=>
item
.
includes
(
'defaultModel='
))?.
replace
(
'defaultModel='
,
''
)
||
'year'
;
_defaultDate
=
MODEL
.
includes
(
_defaultModel
)
?
_defaultDate
:
'year'
;
// 确保值符合要求
if
(
_defaultDate
&&
_defaultDate
.
length
>
1
)
{
_defaultDate
=
{
dateFrom
:
moment
(
_defaultDate
[
0
]),
dateTo
:
moment
(
_defaultDate
[
1
])
};
}
else
if
(
_defaultDate
&&
_defaultDate
.
length
===
1
)
{
...
...
@@ -789,22 +925,47 @@ const ReportsManage = (props) => {
}
else
{
_defaultDate
=
{
dateFrom
:
moment
(),
dateTo
:
moment
()
};
}
// 给定默认值,初始化时可以加载
changeDate
(
{
dateFrom
:
_defaultDate
?.
dateFrom
.
clone
().
startOf
(
_defaultModel
).
format
(
dateFormat
),
dateTo
:
_defaultDate
?.
dateTo
.
clone
().
endOf
(
_defaultModel
).
format
(
dateFormat
),
},
_defaultModel
,
);
setDefaultDateConfig
({
defaultDate
:
_defaultDate
?.
dateFrom
,
defaultModel
:
_configItems
.
find
((
item
)
=>
item
.
includes
(
'defaultModel='
))?.
replace
(
'defaultModel='
,
''
)
||
'year'
,
defaultModel
:
_defaultModel
,
});
};
const
focusProject
=
(
record
)
=>
{
reportService
.
setReportAllow
({
userId
:
USER_ID
,
reportName
:
reportName
,
reportKey
:
record
.
Key
,
})
.
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
message
.
success
(
`
${
record
.
IsAllow
?
'取消'
:
'关注'
}
成功!`
);
getData
(
pagination
);
}
else
{
message
.
error
(
`
${
record
.
IsAllow
?
'取消'
:
'关注'
}
失败!`
);
}
});
};
useEffect
(()
=>
{
get
Data
(
true
,
pagination
);
get
Configs
(
);
},
[]);
useEffect
(()
=>
{
if
(
firstToGetData
)
getData
(
pagination
);
},
[
firstToGetData
]);
useEffect
(()
=>
{
if
(
tableHeaderLevel
)
setTableHeight
();
},
[
tableHeaderLevel
]);
useEffect
(()
=>
{
getData
(
false
,
pagination
);
},
[
timeFrom
,
timeTo
,
filterObject
]);
if
(
!
isInit
)
getData
(
pagination
);
},
[
timeFrom
,
timeTo
,
sorterObject
,
filterObject
]);
useEffect
(()
=>
{
function
getRefHeight
()
{
if
(
timer
)
clearTimeout
(
timer
);
...
...
@@ -832,94 +993,112 @@ const ReportsManage = (props) => {
{
/* 为方便阅读,分开两部分代码 */
}
{
!
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'
)
?
(
<
DatePickerGroup
showModels
=
{[
'all'
,
'month'
,
'quarter'
,
'year'
,
'custom'
]}
onChange
=
{
changeDate
}
format
=
{
dateFormat
}
defaultModel
=
{
defaultDateConfig
.
defaultModel
}
defaultDate
=
{
defaultDateConfig
.
defaultDate
}
<
Row
className
=
{
style
.
controlRow
}
ref
=
{
controlRef
}
>
<
Space
style
=
{{
flex
:
1
}}
size
=
{
8
}
wrap
=
{
true
}
>
{
/*时间搜索控件,确保时间搜索控件在第一个,单独匹配*/
}
{
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
}
fieldAlias
=
{
control
.
fieldAlias
}
configItems
=
{
control
.
configItems
}
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
)
=>
{
searchInputChange
(
e
);
}}
onSearch
=
{
searchData
}
/
>
)
:
(
''
)}
{
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
=
{
'快速搜索控件'
}
>
<
ReturnControlComponent
placeholder
=
{
`请输入
${
searchPlaceholder
.
length
?
searchPlaceholder
.
join
(
','
)
:
'关键字'
}
搜索`
}
style
=
{{
width
:
240
}}
type
=
{
'文本'
}
onChange
=
{(
e
)
=>
{
searchInputChange
(
e
);
}}
onSearch
=
{
searchData
}
/
>
<
/Form.Item
>
)
:
(
''
)}
<
/Space
>
{
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
>
)
:
(
''
)}
<
/Space
>
<
/div
>
<
/Form.Item
>
)
:
(
''
)}
<
/Row
>
)
:
(
''
)}
<
/Space
>
{
permission
.
includes
(
'sortBtn'
)
||
permission
.
includes
(
'exportBtn'
)
?
(
<
div
style
=
{{
width
:
270
,
textAlign
:
'end'
}}
>
<
Space
size
=
{
8
}
nowrap
>
{
permission
.
includes
(
'addBtn'
)
?
(
<
Form
.
Item
>
<
Button
type
=
{
'primary'
}
title
=
{
'自定义排序'
}
icon
=
{
<
PlusOutlined
/>
}
onClick
=
{()
=>
{
setModalType
(
'新增'
);
setCurrentData
({});
}}
>
添加
<
/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
style
=
{{
float
:
'right'
}}
overlay
=
{
menu
}
>
<
Button
>
<
Space
>
导出
<
DownOutlined
/>
<
/Space
>
<
/Button
>
<
/Dropdown
>
<
/Form.Item
>
)
:
(
''
)}
<
/Space
>
<
/div
>
)
:
(
''
)}
<
/Row
>
<
div
className
=
{
style
.
tableContent
}
style
=
{{
height
:
`calc(100% -
${
controlsHeight
||
0
}
px)`
}}
...
...
@@ -932,8 +1111,7 @@ const ReportsManage = (props) => {
dataSource
=
{
tableData
}
columns
=
{
columns
}
onChange
=
{(
pagination
,
filters
,
sorter
,
extra
)
=>
{
console
.
log
(
sorter
);
setSorter
(
sorter
);
setSorterObject
(
sorter
);
}}
pagination
=
{
permission
.
includes
(
'pagination'
)
?
pagination
:
false
}
// 237是内置图片高度
...
...
@@ -1058,7 +1236,7 @@ const ReportsManage = (props) => {
<
Button
type
=
{
'primary'
}
onClick
=
{()
=>
{
saveReportListSortFields
(()
=>
getData
(
false
,
pagination
));
saveReportListSortFields
(()
=>
getData
(
pagination
));
setModalVisible
(
false
);
}}
>
...
...
@@ -1114,19 +1292,21 @@ const ReportsManage = (props) => {
<
/Modal
>
{
/* 编辑表单 */
}
<
Modal
title
=
{
'编辑报表信息'
}
visible
=
{
editComponentVisibl
e
}
title
=
{
`
${
modalType
}
报表信息`
}
visible
=
{
!!
modalTyp
e
}
width
=
{
'80%'
}
footer
=
{
null
}
// visible={true}
onCancel
=
{()
=>
setEditComponentVisible
(
false
)}
destroyOnClose
onCancel
=
{()
=>
setModalType
(
''
)}
>
<
ReportEditForm
modalType
=
{
modalType
}
reportDetails
=
{
tableStruct
}
reportData
=
{
currentData
}
onCancel
=
{()
=>
{
set
EditComponentVisible
(
false
);
getData
(
false
,
pagination
);
set
ModalType
(
''
);
getData
(
pagination
);
}}
reportName
=
{
reportName
}
/
>
...
...
packages/base-components/BasicReport/src/ReportsManage/ReportsSetting.js
View file @
437dd7ca
...
...
@@ -15,6 +15,8 @@ import {
MenuOutlined
,
SettingOutlined
,
LeftOutlined
,
ExportOutlined
,
ImportOutlined
,
}
from
'@ant-design/icons'
;
import
{
Button
,
...
...
@@ -30,6 +32,8 @@ import {
Space
,
Switch
,
Tooltip
,
Table
,
Upload
,
}
from
'antd'
;
import
{
SketchPicker
}
from
'react-color'
;
import
{
arrayMoveImmutable
}
from
'array-move'
;
...
...
@@ -38,16 +42,23 @@ import { reportService } from '../api';
import
style
from
'./ReportsSetting.less'
;
import
classname
from
'classnames'
;
import
{
SortableContainer
,
SortableElement
,
SortableHandle
}
from
'react-sortable-hoc'
;
import
{
addReportDetailInfoIndex
}
from
'../api/service/report'
;
import
{
addReportDetailInfoIndex
,
API
,
exportReportConfig
,
importReportConfig
,
}
from
'../api/service/report'
;
import
{
isNumber
,
isString
}
from
'./utils/utils'
;
import
moment
from
'moment'
;
import
CustomerColorPicker
from
'./Components/customerColorPicker/CustomerColorPicker'
;
const
{
Option
}
=
Select
;
const
{
TextArea
}
=
Input
;
const
{
Search
}
=
Input
;
const
typeArray
=
[
'文本'
,
'标签'
,
'数值'
,
'链接'
,
'功能'
,
'弹窗'
,
'日期'
,
'日期时间'
];
const
typeArray
=
[
'文本'
,
'标签'
,
'数值'
,
'链接'
,
'功能'
,
'弹窗'
,
'日期'
,
'日期时间'
,
'附件'
];
const
filterRule
=
[
'文本'
,
'下拉'
,
'多选'
,
'日期'
];
const
publicSplit
=
'&split;'
;
const
USER_ID
=
window
.
globalConfig
.
userInfo
.
OID
;
const
ReportsSetting
=
()
=>
{
// 报表列表
const
layout
=
{
...
...
@@ -120,6 +131,7 @@ const ReportsSetting = () => {
clickReport
(
record
.
id
);
}}
/
>
<
ExportOutlined
title
=
{
'导出配置'
}
onClick
=
{()
=>
exportConfigs
(
record
)}
/
>
<
DeleteOutlined
title
=
{
'删除报表'
}
style
=
{{
color
:
'red'
}}
...
...
@@ -161,8 +173,41 @@ const ReportsSetting = () => {
const
[
patchSubTableBtnLoading
,
setPatchSubTableBtnLoading
]
=
useState
(
false
);
const
[
isEditing
,
setIsEditing
]
=
useState
(
true
);
const
[
detailTableLoading
,
setDetailTableLoading
]
=
useState
(
false
);
const
[
selectedRowKeys
,
setSelectedRowKeys
]
=
useState
([]);
const
[
selectedRows
,
setSelectedRows
]
=
useState
([]);
const
SortableItem
=
SortableElement
((
props
)
=>
<
tr
{...
props
}
/>
)
;
const
SortableBody
=
SortableContainer
((
props
)
=>
<
tbody
{...
props
}
/>
)
;
// 导入配置
const
uploadProps
=
{
action
:
`
${
window
.
location
.
origin
}${
API
.
IMPORT_REPORT_DATA
}
`
,
multiple
:
false
,
showUploadList
:
false
,
headers
:
{
'Content-Type'
:
'multipart/form-data'
,
},
withCredentials
:
true
,
customRequest
({
action
,
file
,
headers
,
withCredentials
})
{
const
formData
=
new
FormData
();
formData
.
append
(
'file'
,
file
);
const
_data
=
{
userId
:
USER_ID
};
importReportConfig
(
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
,
},
},
{
...
_data
},
formData
,
).
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
message
.
success
(
'导入成功!'
);
getData
();
}
else
{
message
.
info
(
res
.
msg
);
}
});
},
};
const
onSortEnd
=
({
oldIndex
,
newIndex
})
=>
{
if
(
oldIndex
!==
newIndex
)
{
const
newData
=
arrayMoveImmutable
(
detailData
.
slice
(),
oldIndex
,
newIndex
).
filter
(
...
...
@@ -217,33 +262,19 @@ const ReportsSetting = () => {
dataIndex
:
'fieldName'
,
key
:
'fieldName'
,
},
{
title
:
'别名'
,
dataIndex
:
'fieldAlias'
,
key
:
'fieldAlias'
,
render
:
(
text
,
record
,
index
)
=>
{
return
isEditing
?
(
<
Form
.
Item
name
=
{[
index
,
'fieldAlias'
]}
rules
=
{[
{
required
:
true
,
message
:
'请输入字段别名'
,
/* {
title: '别名',
dataIndex: 'fieldAlias',
key: 'fieldAlias',
render: (text, record, index) => {
return isEditing ? <Form.Item name={[index, 'fieldAlias']} rules={[{
required: true,
message: '请输入字段别名',
}]}><Input key={`fieldAlias_${index}`} value={record?.fieldAlias}
className={returnEqual(index, 'fieldAlias') ? style.boxShadow : ''}
onChange={(e) => modifyDetailData('fieldAlias', e.target.value, record, index)} /></Form.Item> : text;
},
]}
>
<
Input
key
=
{
`fieldAlias_
${
index
}
`
}
value
=
{
record
?.
fieldAlias
}
className
=
{
returnEqual
(
index
,
'fieldAlias'
)
?
style
.
boxShadow
:
''
}
onChange
=
{(
e
)
=>
modifyDetailData
(
'fieldAlias'
,
e
.
target
.
value
,
record
,
index
)}
/
>
<
/Form.Item
>
)
:
(
text
);
},
},
}, */
{
title
:
'字段组'
,
dataIndex
:
'fieldGroup'
,
...
...
@@ -429,15 +460,58 @@ const ReportsSetting = () => {
},
},
{
title
:
'操作'
,
title
:
'是否必填'
,
dataIndex
:
'isRequired'
,
key
:
'isRequired'
,
width
:
100
,
render
:
(
text
,
record
,
index
)
=>
{
return
isEditing
?
(
<
Form
.
Item
name
=
{[
index
,
'isRequired'
]}
valuePropName
=
"checked"
>
<
Switch
onChange
=
{(
e
)
=>
modifyDetailData
(
'isRequired'
,
e
,
record
,
index
)}
checkedChildren
=
"是"
unCheckedChildren
=
"否"
defaultChecked
=
{
false
}
className
=
{
returnEqual
(
index
,
'isRequired'
)
?
style
.
boxShadowOfSwitch
:
''
}
/
>
<
/Form.Item
>
)
:
text
?
(
'是'
)
:
(
'否'
);
},
},
{
title
:
'操作'
,
width
:
80
,
render
:
(
text
,
record
)
=>
{
return
(
<
DeleteOutlined
onClick
=
{()
=>
deleteReportDetail
(
record
.
id
)}
style
=
{{
color
:
'red'
}}
/
>
<
div
style
=
{{
display
:
'flex'
,
justifyContent
:
'space-around'
}}
>
<
FormOutlined
onClick
=
{()
=>
{
setActiveID
(
record
.
id
);
if
(
record
.
color
)
setBackgroundColor
(
record
.
color
);
form
.
setFieldsValue
(
setDefaultValue
(
record
));
setCurrentField
(
setDefaultValue
(
record
));
setDetailVisible
(
true
);
}}
/
>
<
DeleteOutlined
onClick
=
{()
=>
deleteReportDetail
(
record
.
id
)}
style
=
{{
color
:
'red'
}}
/
>
<
/div
>
);
},
},
];
const
rowSelection
=
{
onChange
:
(
selectedRowKeys
,
selectedRows
)
=>
{
setSelectedRowKeys
(
selectedRowKeys
);
setSelectedRows
(
selectedRows
);
},
};
const
wordInputWidth
=
300
;
const
numberInputWidth
=
120
;
const
rangeWidth
=
500
;
...
...
@@ -586,7 +660,9 @@ const ReportsSetting = () => {
if
(
callback
)
callback
();
});
};
// 切换字段的同时,如果数据有修改,那需要保存之前的数据 edit by ChenLong 2022年8月29日
const
changeField
=
(
record
)
=>
{
// submitReportDetails('changeField').then(res => {
setActiveID
(
record
.
id
);
form
.
setFieldsValue
(
setDefaultValue
(
record
));
// 手动设置文字的颜色
...
...
@@ -595,6 +671,7 @@ const ReportsSetting = () => {
setNumberColorPickerArray
(
record
.
numericalConfigs
);
setLabelColorPickerArray
(
record
.
labelConfigs
);
setCurrentField
(
setDefaultValue
(
record
));
// 为了确保前后数据统一
// });
};
const
setDefaultValue
=
(
record
)
=>
{
if
(
!
record
)
return
{};
...
...
@@ -618,9 +695,10 @@ const ReportsSetting = () => {
if
(
!
_record
.
alignType
)
_record
.
alignType
=
'left'
;
return
_record
;
};
const
submitReportDetails
=
()
=>
{
// @params: {type:String} 不传入type,默认提交表单、关闭表单;传入type时
const
submitReportDetails
=
(
type
)
=>
{
// 1.表单内的值;2.标签值
form
.
validateFields
().
then
((
value
)
=>
{
return
form
.
validateFields
().
then
((
value
)
=>
{
// 需要将表单内带索引的fieldGroup_[number]处理成后端需要的fieldGroups: a-b-c-d;
value
.
fieldGroup
=
Object
.
values
(
value
.
fieldGroup
).
join
(
'-'
);
let
_value
=
Object
.
assign
(
currentField
,
value
);
...
...
@@ -670,7 +748,9 @@ const ReportsSetting = () => {
message
.
error
(
res
.
msg
);
}
setSubmitFieldLoading
(
false
);
setDetailVisible
(
false
);
if
(
!
type
)
{
setDetailVisible
(
false
);
}
clickReport
(
currentReport
.
id
);
});
});
...
...
@@ -763,6 +843,7 @@ const ReportsSetting = () => {
// setIsEditing(true);
};
const
submitDetailFromTable
=
()
=>
{
setDetailTableLoading
(
true
);
editDetailForm
.
validateFields
().
then
((
res
)
=>
{
// 去除掉标签、数字区间内的id
let
_detailData
=
detailData
.
map
((
item
)
=>
{
...
...
@@ -779,17 +860,22 @@ const ReportsSetting = () => {
});
return
_item
;
});
reportService
.
addReportDetailInfo
({
reportDetails
:
_detailData
}).
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
message
.
success
(
'提交成功!'
);
// setIsEditing(false);
}
else
{
message
.
error
(
res
.
msg
);
}
setSubmitFieldLoading
(
false
);
setDetailVisible
(
false
);
clickReport
(
currentReport
.
id
);
});
reportService
.
addReportDetailInfo
({
reportDetails
:
_detailData
})
.
then
((
res
)
=>
{
if
(
res
.
code
===
0
)
{
message
.
success
(
'提交成功!'
);
}
else
{
message
.
error
(
res
.
msg
);
}
setDetailTableLoading
(
false
);
setSubmitFieldLoading
(
false
);
setDetailVisible
(
false
);
clickReport
(
currentReport
.
id
);
})
.
catch
((
err
)
=>
{
setDetailTableLoading
(
false
);
});
});
};
const
patchSubTable2MainTable
=
()
=>
{
...
...
@@ -882,7 +968,11 @@ const ReportsSetting = () => {
}
let
{
data
,
callback
,
index
,
key
}
=
currentColorPicker
;
let
_data
=
[...
data
];
_data
[
index
][
key
]
=
`rgba(
${
_rgb
.
r
}
,
${
_rgb
.
g
}
,
${
_rgb
.
b
}
,
${
_rgb
.
a
}
)`
;
if
(
currentColorPicker
.
key
===
'tagColor'
)
{
_data
[
index
].
color
=
e
;
}
else
{
_data
[
index
][
key
]
=
`rgba(
${
_rgb
.
r
}
,
${
_rgb
.
g
}
,
${
_rgb
.
b
}
,
${
_rgb
.
a
}
)`
;
}
callback
(
_data
);
};
const
returnCurrentColor
=
()
=>
{
...
...
@@ -890,67 +980,6 @@ const ReportsSetting = () => {
if
(
key
===
'init'
)
return
'rgba(0,0,0,.65)'
;
return
data
[
index
][
key
];
};
// 颜色卡片组件
//[
// "rgb(255, 255, 255)",
// "rgb(214, 229, 255)",
// "rgb(214, 241, 255)",
// "rgb(211, 243, 226)",
// "rgb(255, 220, 219)",
// "rgb(255, 236, 219)",
// "rgb(255, 245, 204)",
// "rgb(251, 219, 255)",
// "rgb(255, 219, 234)",
// "rgb(220, 223, 228)",
// "rgb(173, 203, 255)",
// "rgb(173, 228, 255)",
// "rgb(172, 226, 197)",
// "rgb(255, 181, 179)",
// "rgb(255, 206, 163)",
// "rgb(255, 234, 153)",
// "rgb(231, 180, 255)",
// "rgb(255, 179, 220)",
// "rgb(129, 134, 143)",
// "rgb(41, 114, 244)",
// "rgb(0, 163, 245)",
// "rgb(69, 176, 118)",
// "rgb(222, 60, 54)",
// "rgb(248, 136, 37)",
// "rgb(231, 180, 255)",
// "rgb(154, 56, 215)",
// "rgb(221, 64, 151)"
// ]
const
ColorBoard
=
({
value
,
onChange
})
=>
{
return
(
<>
<
div
style
=
{{
padding
:
4
,
display
:
'inline-flex'
,
borderRadius
:
'2px'
,
border
:
'1px solid rgba(0,0,0,.35)'
,
}}
>
<
div
style
=
{{
width
:
'36px'
,
height
:
'14px'
,
borderRadius
:
'2px'
,
border
:
'1px solid rgba(0,0,0,.35)'
,
backgroundColor
:
value
||
'rgba(0,0,0,.65)'
,
}}
onClick
=
{(
e
)
=>
{
clickColorCard
(
e
);
setCurrentColorPicker
({
key
:
'wordColor'
,
callback
:
onChange
,
});
}}
/
>
<
/div
>
<
/
>
);
};
// 拖拽
const
DragHandle
=
SortableHandle
(()
=>
(
<
MenuOutlined
...
...
@@ -993,6 +1022,42 @@ const ReportsSetting = () => {
_data
.
splice
(
index
,
1
,
_record
);
setDetailData
(
_data
);
};
const
batchModify
=
(
key
,
value
)
=>
{
console
.
log
(
key
,
':'
,
value
);
// 1.取出勾选的字段;2.批量修改值
if
(
selectedRowKeys
.
length
===
0
)
return
message
.
info
(
'未勾选任何字段'
);
let
_detailData
=
detailData
.
map
((
item
)
=>
{
let
_item
=
{
...
item
};
if
(
selectedRowKeys
.
includes
(
_item
.
id
))
{
_item
[
key
]
=
value
;
}
return
_item
;
});
setDetailData
(
_detailData
);
editDetailForm
.
setFieldsValue
(
_detailData
);
};
const
exportConfigs
=
(
record
)
=>
{
setTableLoading
(
true
);
exportReportConfig
(
{
responseType
:
'blob'
},
{
reportId
:
record
.
id
,
},
).
then
((
res
)
=>
{
setTableLoading
(
false
);
if
(
res
&&
res
.
code
===
-
1
)
return
message
.
error
(
res
.
msg
);
const
url
=
window
.
URL
.
createObjectURL
(
new
Blob
([
res
],
{
type
:
'application/json;charset=UTF-8'
}),
);
const
a
=
document
.
createElement
(
'a'
);
a
.
href
=
url
;
a
.
target
=
'_blank'
;
a
.
download
=
`
${
record
.
reportName
}
.json`
;
a
.
click
();
a
.
remove
();
});
};
useEffect
(()
=>
{
getData
();
},
[]);
...
...
@@ -1026,42 +1091,32 @@ const ReportsSetting = () => {
top
:
colorCardPosition
.
top
,
}}
>
<
SketchPicker
width
=
{
240
}
presetColors
=
{[
'rgb(255, 255, 255)'
,
'rgb(214, 229, 255)'
,
'rgb(214, 241, 255)'
,
'rgb(211, 243, 226)'
,
'rgb(255, 220, 219)'
,
'rgb(255, 236, 219)'
,
'rgb(255, 245, 204)'
,
'rgb(251, 219, 255)'
,
'rgb(255, 219, 234)'
,
'rgb(220, 223, 228)'
,
'rgb(173, 203, 255)'
,
'rgb(173, 228, 255)'
,
'rgb(172, 226, 197)'
,
'rgb(255, 181, 179)'
,
'rgb(255, 206, 163)'
,
'rgb(255, 234, 153)'
,
'rgb(231, 180, 255)'
,
'rgb(255, 179, 220)'
,
'rgb(129, 134, 143)'
,
'rgb(41, 114, 244)'
,
'rgb(0, 163, 245)'
,
'rgb(69, 176, 118)'
,
'rgb(222, 60, 54)'
,
'rgb(248, 136, 37)'
,
'rgb(216,180,255)'
,
'rgb(154, 56, 215)'
,
'rgb(221, 64, 151)'
,
]}
color
=
{
currentColorPicker
.
key
===
'wordColor'
?
backgroundColor
:
returnCurrentColor
()
}
onChange
=
{(
e
)
=>
changeBackgroundColor
(
e
)}
/
>
{
currentColorPicker
.
key
===
'tagColor'
?
(
<
CustomerColorPicker
clickColorPicker
=
{(
backgroundColor
)
=>
{
changeBackgroundColor
(
backgroundColor
);
}}
/
>
)
:
(
<
SketchPicker
width
=
{
240
}
presetColors
=
{[
'rgb(129, 134, 143)'
,
'rgb(41, 114, 244)'
,
'rgb(0, 163, 245)'
,
'rgb(69, 176, 118)'
,
'rgb(222, 60, 54)'
,
'rgb(248, 136, 37)'
,
'rgb(216,180,255)'
,
'rgb(154, 56, 215)'
,
'rgb(221, 64, 151)'
,
]}
color
=
{
currentColorPicker
.
key
===
'wordColor'
?
backgroundColor
:
returnCurrentColor
()
}
onChange
=
{(
e
)
=>
changeBackgroundColor
(
e
)}
/
>
)}
<
/div
>
<
/div
>
<
Modal
...
...
@@ -1199,7 +1254,7 @@ const ReportsSetting = () => {
)}
key
=
{
item
.
id
}
>
{
item
.
field
Name
}
{
item
.
field
Alias
}
<
/li
>
))}
<
/ul
>
...
...
@@ -1228,13 +1283,18 @@ const ReportsSetting = () => {
>
<
Input
disabled
style
=
{{
width
:
wordInputWidth
}}
/
>
<
/Form.Item
>
{
/* <Form.Item label={'别名'} name={'fieldAlias'} rules={[
{
required: true, message: '别名必填且不可重复',
},
]}>
<Input style={{ width: wordInputWidth }} />
</Form.Item>*/
}
<
Form
.
Item
label
=
{
'别名'
}
name
=
{
'fieldAlias'
}
rules
=
{[
{
required
:
true
,
message
:
'别名必填且不可重复'
,
},
]}
>
<
Input
style
=
{{
width
:
wordInputWidth
}}
/
>
<
/Form.Item
>
<
Form
.
Item
label
=
{
'表头级数'
}
name
=
{
'level'
}
...
...
@@ -1314,13 +1374,6 @@ const ReportsSetting = () => {
/
>
<
/div
>
<
/Form.Item
>
{
/* <Form.Item label={'对齐方式'} name={'alignType'}>
<Radio.Group>
<Radio value={'left'}>左</Radio>
<Radio value={'center'}>中</Radio>
<Radio value={'right'}>右</Radio>
</Radio.Group>
</Form.Item>*/
}
{
watchType
===
'数值'
?
(
<
Form
.
Item
label
=
{
'区间设置'
}
>
{
numberColorPickerArray
.
map
((
item
,
index
)
=>
{
...
...
@@ -1535,7 +1588,7 @@ const ReportsSetting = () => {
data
:
labelColorPickerArray
,
callback
:
setLabelColorPickerArray
,
index
,
key
:
'
c
olor'
,
key
:
'
tagC
olor'
,
});
}}
/
>
...
...
@@ -1623,7 +1676,9 @@ const ReportsSetting = () => {
/
>
<
/Form.Item
>
<
Form
.
Item
>
<
Button
onClick
=
{
showPatchSubModal
}
>
附加子表
<
/Button
>
<
Button
style
=
{{
marginRight
:
8
}}
onClick
=
{
showPatchSubModal
}
>
附加子表
<
/Button
>
<
Button
onClick
=
{
addVirtualColumn
}
>
添加虚拟字段
<
/Button
>
<
/Form.Item
>
<
/div
>
...
...
@@ -1641,6 +1696,7 @@ const ReportsSetting = () => {
<
/Button
>
<
Button
type
=
{
'primary'
}
loading
=
{
detailTableLoading
}
style
=
{{
marginRight
:
8
}}
onClick
=
{
submitDetailFromTable
}
>
...
...
@@ -1661,10 +1717,6 @@ const ReportsSetting = () => {
)}
<
/Form.Item
>
<
/Form
>
{
/* <Button type={'primary'} onClick={() => {
setDetailTableVisible(false);
// setIsEditing(false);
}}>返回</Button>*/
}
<
/Row
>
<
div
className
=
{
style
.
tableContent
}
>
<
Form
className
=
{
style
.
tableForm
}
form
=
{
editDetailForm
}
>
...
...
@@ -1672,10 +1724,102 @@ const ReportsSetting = () => {
loading
=
{
detailTableLoading
}
pagination
=
{
false
}
bordered
scroll
=
{{
y
:
'calc(100% - 40px)'
}}
scroll
=
{{
y
:
`calc(100% -
${
selectedRowKeys
.
length
?
90
:
40
}
px)`
}}
// 需要考虑总结栏的高度
rowKey
=
{
'id'
}
columns
=
{
detailColumns
}
rowSelection
=
{
isEditing
?
{
type
:
'checkbox'
,
...
rowSelection
,
}
:
null
}
dataSource
=
{
detailData
.
filter
((
item
)
=>
item
.
visible
)}
summary
=
{(
pageData
)
=>
{
if
(
detailData
&&
detailData
.
length
>
1
&&
isEditing
&&
selectedRows
.
length
)
{
return
(
<
Table
.
Summary
fixed
>
<
Table
.
Summary
.
Row
>
<
Table
.
Summary
.
Cell
colSpan
=
{
7
}
>
批量操作
<
/Table.Summary.Cell
>
<
Table
.
Summary
.
Cell
>
<
Form
.
Item
>
<
InputNumber
onChange
=
{(
e
)
=>
batchModify
(
'columnWidth'
,
e
)}
/
>
<
/Form.Item
>
<
/Table.Summary.Cell
>
<
Table
.
Summary
.
Cell
>
<
Form
.
Item
>
<
Select
onChange
=
{(
e
)
=>
batchModify
(
'alignType'
,
e
)}
>
<
Option
value
=
{
'left'
}
>
左
<
/Option
>
<
Option
value
=
{
'center'
}
>
中
<
/Option
>
<
Option
value
=
{
'right'
}
>
右
<
/Option
>
<
/Select
>
<
/Form.Item
>
<
/Table.Summary.Cell
>
<
Table
.
Summary
.
Cell
>
<
Form
.
Item
>
<
Select
onChange
=
{(
e
)
=>
batchModify
(
'fixedColumn'
,
e
)}
>
<
Option
value
=
{
''
}
>
不固定
<
/Option
>
<
Option
value
=
{
'left'
}
>
左
<
/Option
>
<
Option
value
=
{
'right'
}
>
右
<
/Option
>
<
/Select
>
<
/Form.Item
>
<
/Table.Summary.Cell
>
<
Table
.
Summary
.
Cell
>
<
Form
.
Item
>
<
Switch
checkedChildren
=
"显示"
unCheckedChildren
=
"不显示"
defaultChecked
=
{
false
}
onChange
=
{(
e
)
=>
batchModify
(
'isShow'
,
e
)}
/
>
<
/Form.Item
>
<
/Table.Summary.Cell
>
<
Table
.
Summary
.
Cell
>
<
Form
.
Item
>
<
Switch
checkedChildren
=
"开启"
unCheckedChildren
=
"关闭"
defaultChecked
=
{
false
}
onChange
=
{(
e
)
=>
batchModify
(
'isFilter'
,
e
)}
/
>
<
/Form.Item
>
<
/Table.Summary.Cell
>
<
Table
.
Summary
.
Cell
>
<
Form
.
Item
>
<
Select
onChange
=
{(
e
)
=>
batchModify
(
'isFilter'
,
e
)}
>
<
Option
value
=
{
''
}
>
不过滤
<
/Option
>
<
Option
value
=
{
'文本'
}
>
文本
<
/Option
>
<
Option
value
=
{
'下拉'
}
>
下拉
<
/Option
>
<
Option
value
=
{
'多选'
}
>
多选
<
/Option
>
<
Option
value
=
{
'日期'
}
>
日期
<
/Option
>
<
/Select
>
<
/Form.Item
>
<
/Table.Summary.Cell
>
<
Table
.
Summary
.
Cell
>
<
Form
.
Item
>
<
Switch
checkedChildren
=
"开启"
unCheckedChildren
=
"关闭"
defaultChecked
=
{
false
}
onChange
=
{(
e
)
=>
batchModify
(
'isMerge'
,
e
)}
/
>
<
/Form.Item
>
<
/Table.Summary.Cell
>
<
Table
.
Summary
.
Cell
>
<
Form
.
Item
>
<
DeleteOutlined
onClick
=
{()
=>
batchModify
(
'delete'
)}
title
=
{
'批量删除'
}
style
=
{{
color
:
'red'
}}
/
>
<
/Form.Item
>
<
/Table.Summary.Cell
>
<
/Table.Summary.Row
>
<
/Table.Summary
>
);
}
}}
components
=
{
isEditing
?
''
...
...
@@ -1689,6 +1833,7 @@ const ReportsSetting = () => {
onRow
=
{(
record
)
=>
{
return
{
onDoubleClick
:
(
e
)
=>
{
return
false
;
if
(
e
.
target
.
cellIndex
===
detailColumns
.
length
-
1
||
e
.
target
.
cellIndex
===
void
0
...
...
@@ -1794,6 +1939,7 @@ const ReportsSetting = () => {
<
Form
.
Item
>
<
Button
type
=
{
'primary'
}
style
=
{{
marginRight
:
8
}}
onClick
=
{()
=>
openCreateModal
(()
=>
{
setCurrentReport
({});
...
...
@@ -1809,6 +1955,11 @@ const ReportsSetting = () => {
>
新增
<
/Button
>
<
Upload
{...
uploadProps
}
>
<
Button
size
=
"middle"
icon
=
{
<
ImportOutlined
/>
}
>
导入
<
/Button
>
<
/Upload
>
<
/Form.Item
>
<
/Form
>
<
/Row
>
...
...
packages/base-components/BasicReport/src/ReportsManage/utils/constant.js
0 → 100644
View file @
437dd7ca
const
tagColors
=
[
'rgb(129, 134, 143)'
,
'rgb(41, 114, 244)'
,
'rgb(0, 163, 245)'
,
'rgb(69, 176, 118)'
,
'rgb(222, 60, 54)'
,
'rgb(248, 136, 37)'
,
'rgb(189, 160, 20)'
,
'rgb(154, 56, 215)'
,
'rgb(221, 64, 151)'
,
];
const
tagBackgroundColors
=
[
'rgb(220, 223, 228)'
,
'rgb(214, 229, 255)'
,
'rgb(214, 241, 255)'
,
'rgb(211, 243, 226)'
,
'rgb(255, 220, 219)'
,
'rgb(255, 236, 219)'
,
'rgb(255, 245, 204)'
,
'rgb(251, 219, 255)'
,
'rgb(255, 219, 234)'
,
];
export
{
tagColors
,
tagBackgroundColors
};
packages/base-components/BasicReport/src/ReportsManage/utils/handlers.js
View file @
437dd7ca
...
...
@@ -8,7 +8,8 @@ import { hasMoney, isNumber } from './utils';
* @params: config下的数值的configRule结构如下,[{最大值: 10,最小值: 0,颜色:'#AAAAAA'}];
* @business: configRule有值,则按照configRule设置;没有,按照color设置; 有最大值,无最小值;['', 1]
* 有最大值,有最小值;[2,
* 10]
*
* 10]
* 有最小值,无最大值;[11,'']
*/
// 链接 功能 弹窗功能待提出需求
...
...
@@ -76,7 +77,8 @@ const returnOpacity = (rgba) => {
};
export
const
handleNumber
=
(
config
,
number
)
=>
{
let
_color
=
''
;
if
(
number
)
number
=
Number
(
number
);
// 当设置精度后,会被转成字符串
let
_number
;
if
(
number
)
_number
=
Number
(
number
);
// 当设置精度后,会被转成字符串
if
(
config
.
numericalConfigs
&&
config
.
numericalConfigs
.
length
)
{
config
.
numericalConfigs
.
forEach
((
item
)
=>
{
// 接口对于数值类型的返回为null
...
...
@@ -84,11 +86,11 @@ export const handleNumber = (config, number) => {
let
_max
=
item
.
maxValue
||
''
;
let
_min
=
item
.
minValue
||
''
;
if
(
_max
!==
''
&&
_min
===
''
)
{
_color
=
number
<=
Number
(
_max
)
?
''
:
item
.
color
;
_color
=
_
number
<=
Number
(
_max
)
?
''
:
item
.
color
;
}
else
if
(
_min
!==
''
&&
_max
===
''
)
{
_color
=
number
>
Number
(
_min
)
?
item
.
color
:
''
;
_color
=
_
number
>
Number
(
_min
)
?
item
.
color
:
''
;
}
else
{
_color
=
number
>
Number
(
_min
)
&&
number
<=
Number
(
_max
)
?
item
.
color
:
''
;
_color
=
_number
>
Number
(
_min
)
&&
_
number
<=
Number
(
_max
)
?
item
.
color
:
''
;
}
}
});
...
...
@@ -144,15 +146,23 @@ export const handleTag = (config, text) => {
}
_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]}`,
borderRadius: 4,
color: `rgba(0, 0, 0, .65)`,
}}>{item}</Tag>);*/
.
map
((
item
)
=>
(
<
Tag
style
=
{{
background
:
_map
[
item
]
||
_color
,
border
:
`1px solid
${
_map
[
item
]
||
_color
}
`
,
borderRadius
:
2
,
color
:
_map
[
item
]
?
tagColors
[
tagBackgroundColors
.
findIndex
((
c
)
=>
c
===
_map
[
item
])]
:
`rgba(0, 0, 0, .65)`
,
}}
>
{
item
}
<
/Tag
>
));
};
export
const
handleText
=
(
config
,
text
)
=>
{
return
<
span
style
=
{{
color
:
config
.
color
||
'rgba(0,0,0,.85)'
}}
>
{
text
}
<
/span>
;
...
...
packages/base-components/BasicReport/src/ReportsManage/utils/utils.js
View file @
437dd7ca
...
...
@@ -24,7 +24,9 @@ const hasMoney = (configItems) => {
const
returnHandledNumber
=
(
configItems
,
num
)
=>
{
// 精度、前缀、后缀、倍率
// $_d|_d%|_d*0.0001|金额|0.00
if
(
isNaN
(
num
))
return
'-'
;
if
(
!
configItems
)
return
num
;
num
=
Number
(
num
);
let
_items
=
configItems
.
split
(
'|'
);
/* let prefix = '';
let suffix = '';*/
...
...
@@ -58,8 +60,10 @@ const returnHandledNumber = (configItems, num) => {
* @author: ChenLong
* @params:
* configItems 报表字段的配置 例如 defaultValue=智慧水务
*
* defaultDateModel=customer|defaultDateValue=2022-01-01,2022-12-31;
* keysArray
*
* 所需要返回的值的key的集合,比如你需要获取configItems中的’defaultValue‘,那么keysArray=['defaultValue'];
* @returns:
* defaultValue 通用参数 默认值
...
...
@@ -74,6 +78,42 @@ const returnDefaultValueOrConfigs = (configItems = '', keysArray = []) => {
});
return
_map
;
};
function
downloadFunc
(
url
,
name
,
target
=
'_self'
)
{
const
a
=
document
.
createElement
(
'a'
);
a
.
href
=
url
;
a
.
target
=
target
;
a
.
download
=
name
;
a
.
click
();
a
.
remove
();
}
/**
* @description: 校验文件的名称是否包含特殊字符
* @params: {Object: File} file file对象 { special:Boolean } 是否去除/的匹配
* @date: 2021/12/8
* @author: ChenLong
* @returns {Object} {type: error | success ,content: 提示...}
*/
function
filenameVerification
(
file
,
special
)
{
debugger
;
// 文件名含有特殊字符 提示不能上传 {+,:/?#[]@!$&\\*+;=}
// 规则对象(flag)
var
flag
=
!
special
?
new
RegExp
(
"[`~!@#$^&*=|{}':;',
\\
[
\\
]/?~!@#¥&*——|{}【】‘;:”“'。,、?]"
)
:
new
RegExp
(
"[`~!@#$^&*=|{}':;',[
\\
]?~!@#¥&*——|{}【】‘;:”“'。,、?]"
);
if
(
flag
.
test
(
file
.
name
))
{
return
{
type
:
'error'
,
content
:
`文件名格式错误,请检查文件名是否含有特殊字符
${
"~!@#$^&*=|{}':;',
\\
[
\\
]/?~!@#¥&*——|{}【】‘;:”“'。,、?"
}
`
,
};
}
return
{
type
:
'success'
,
content
:
`上传成功!`
,
};
}
export
{
isObject
,
isString
,
...
...
@@ -82,4 +122,6 @@ export {
isArray
,
returnHandledNumber
,
returnDefaultValueOrConfigs
,
downloadFunc
,
filenameVerification
,
};
packages/base-components/BasicReport/src/api/service/report.js
View file @
437dd7ca
...
...
@@ -24,6 +24,13 @@ export const API = {
SAVE_REPORT_LIST_SORT_FIELDS
:
`
${
BASEURL
}
/SaveReportListSortFields`
,
// 保存排序
ADD_REPORT_DETAIL_INFO_INDEX
:
`
${
BASEURL
}
/AddReportDetailInfoIndex`
,
// 变更接口顺序
UPDATE_REPORT_DATA
:
`
${
BASEURL
}
/UpdateReportData`
,
// 更新报表数据
GET_REPORT_DETAILS
:
`
${
BASEURL
}
/GetReportDetails`
,
// 获取报表配置
DEL_REPORT_DATA
:
`
${
BASEURL
}
/DelReportData`
,
// 删除报表数据
SET_REPORT_ALLOW
:
`
${
BASEURL
}
/SetReportAllow`
,
// 设置关注
ADD_REPORT_DATA
:
`
${
BASEURL
}
/AddReportData`
,
// 添加报表数据
EXPORT_JPG
:
`
${
BASEURL
}
/ExportJPGAccountData`
,
EXPORT_REPORT_CONFIG
:
`
${
BASEURL
}
/ExportReportConfig`
,
IMPORT_REPORT_CONFIG
:
`
${
BASEURL
}
/ImportReportConfig`
,
};
const
reportService
=
{
getReportInfo
:
{
...
...
@@ -96,6 +103,41 @@ const reportService = {
method
:
constants
.
REQUEST_METHOD_POST
,
type
:
constants
.
REQUEST_METHOD_POST
,
},
getReportDetails
:
{
url
:
API
.
GET_REPORT_DETAILS
,
method
:
constants
.
REQUEST_METHOD_GET
,
type
:
constants
.
REQUEST_METHOD_GET
,
},
delReportData
:
{
url
:
API
.
DEL_REPORT_DATA
,
method
:
constants
.
REQUEST_METHOD_POST
,
type
:
constants
.
REQUEST_METHOD_POST
,
},
setReportAllow
:
{
url
:
API
.
SET_REPORT_ALLOW
,
method
:
constants
.
REQUEST_METHOD_POST
,
type
:
constants
.
REQUEST_METHOD_POST
,
},
addReportData
:
{
url
:
API
.
ADD_REPORT_DATA
,
method
:
constants
.
REQUEST_METHOD_POST
,
type
:
constants
.
REQUEST_METHOD_POST
,
},
exportJPG
:
{
url
:
API
.
EXPORT_JPG
,
method
:
constants
.
REQUEST_METHOD_POST
,
type
:
constants
.
REQUEST_METHOD_POST
,
},
exportConfig
:
{
url
:
API
.
EXPORT_REPORT_CONFIG
,
method
:
constants
.
REQUEST_METHOD_GET
,
type
:
constants
.
REQUEST_METHOD_GET
,
},
importConfig
:
{
url
:
API
.
IMPORT_REPORT_CONFIG
,
method
:
constants
.
REQUEST_METHOD_POST
,
type
:
constants
.
REQUEST_METHOD_POST
,
},
};
export
const
submitReportData
=
(
params
,
data
)
=>
request
({
...
...
@@ -112,10 +154,33 @@ export const exportAccountData = (options, params, data) =>
params
,
data
,
});
export
const
exportJPG
=
(
options
,
data
)
=>
{
return
request
({
url
:
API
.
EXPORT_JPG
,
method
:
'post'
,
...
options
,
data
,
});
};
export
const
addReportDetailInfoIndex
=
(
data
)
=>
request
({
url
:
API
.
ADD_REPORT_DETAIL_INFO_INDEX
,
method
:
'post'
,
data
,
});
export
const
importReportConfig
=
(
options
,
params
,
data
)
=>
request
({
url
:
API
.
IMPORT_REPORT_CONFIG
,
method
:
'post'
,
...
options
,
params
,
data
,
});
export
const
exportReportConfig
=
(
options
,
params
)
=>
request
({
url
:
API
.
EXPORT_REPORT_CONFIG
,
method
:
'get'
,
...
options
,
params
,
});
export
default
reportService
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment