feat(accident): 优化事故管理功能

- 修改事故批量删除接口路径参数格式
- 更新企业信息列表接口路径
- 添加权限控制装饰器和权限配置
- 优化事故查询条件时间范围处理
- 调整事故等级字段显示为"等级"而非"级别"
- 增加表格行选择保持功能
- 完善导出按钮
master
fangjiakai 2025-12-22 10:23:33 +08:00
parent 9e20384ca5
commit 2b9b7dee4e
6 changed files with 69 additions and 55 deletions

View File

@ -18,7 +18,7 @@ export const accidentDelete = declareRequest(
); );
export const accidentBatchDelete = declareRequest( export const accidentBatchDelete = declareRequest(
'accidentLoading', 'accidentLoading',
'Delete > @/accident/accident/ids/{ids}' 'Delete > @/accident/accident/ids?ids={ids}'
); );
export const accidentInfo = declareRequest('accidentLoading', 'Get > /accident/accident/{id}'); export const accidentInfo = declareRequest('accidentLoading', 'Get > /accident/accident/{id}');
@ -29,10 +29,10 @@ export const accidentCountByCorpinfoAndType = declareRequest(
export const getCorpInfoList = declareRequest( export const getCorpInfoList = declareRequest(
'accidentLoading', 'accidentLoading',
'Post > @/basic-info/corpInfo/list' 'Post > @/basicInfo/corpInfo/list'
); );
export const accidentExport = declareRequest( export const accidentExport = declareRequest(
'accidentLoading', 'accidentLoading',
'Post > @/accident/accident/export' 'Post > @/accident/accident/export'
); );

View File

@ -20,6 +20,9 @@ import HeaderBack from "zy-react-library/components/HeaderBack";
import DictionarySelect from "zy-react-library/components/Select/Dictionary"; import DictionarySelect from "zy-react-library/components/Select/Dictionary";
import useDownloadBlob from "zy-react-library/hooks/useDownloadBlob"; import useDownloadBlob from "zy-react-library/hooks/useDownloadBlob";
import useUrlQueryCriteria from "zy-react-library/hooks/useUrlQueryCriteria"; import useUrlQueryCriteria from "zy-react-library/hooks/useUrlQueryCriteria";
import PreviewImg from "zy-react-library/components/PreviewImg";
import useDownloadFile from "zy-react-library/hooks/useDownloadFile";
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
function Accident(props) { function Accident(props) {
@ -29,7 +32,7 @@ function Accident(props) {
const [accidentId, setAccidentId] = useState(""); const [accidentId, setAccidentId] = useState("");
const [selectedRowKeys, setSelectedRowKeys] = useState([]); const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const { loading, downloadBlob } = useDownloadBlob(); const { loading, downloadBlob } = useDownloadBlob();
const {getUrlCriteriaQuery} = useUrlQueryCriteria(); const { getUrlCriteriaQuery } = useUrlQueryCriteria();
const [form] = Form.useForm(); const [form] = Form.useForm();
const { tableProps, getData } = useTable(props["accidentList"], { const { tableProps, getData } = useTable(props["accidentList"], {
form, form,
@ -38,8 +41,8 @@ function Accident(props) {
eqCorpinfoId: props.corpinfoId, eqCorpinfoId: props.corpinfoId,
}, },
transform: data => ({ transform: data => ({
geIncidentDate: data.incidentDate?.[0], geIncidentDate: data.incidentDate?.[0] ? (data.incidentDate[0] + " 00:00:00") : "",
leIncidentDate: data.incidentDate?.[1], leIncidentDate: data.incidentDate?.[1] ? (data.incidentDate[1] + " 23:59:59") : "",
}), }),
}); });
const typeName = props.type === 1 ? "事件" : "事故"; const typeName = props.type === 1 ? "事件" : "事故";
@ -52,7 +55,7 @@ function Accident(props) {
options={[ options={[
{ name: "likeIncidentName", label: `${typeName}名称` }, { name: "likeIncidentName", label: `${typeName}名称` },
{ name: "eqIncidentType", label: `${typeName}类型`, render: <DictionarySelect dictValue="accidentType" /> }, { name: "eqIncidentType", label: `${typeName}类型`, render: <DictionarySelect dictValue="accidentType" /> },
{ name: "eqIncidentLevel", label: `${typeName}`, render: <DictionarySelect dictValue="accidentLevel" /> }, { name: "eqIncidentLevel", label: `${typeName}`, render: <DictionarySelect dictValue="accidentLevel" /> },
{ name: "likeLocation", label: `${typeName}发生地点` }, { name: "likeLocation", label: `${typeName}发生地点` },
{ name: "incidentDate", label: `${typeName}发生时间`, render: FORM_ITEM_RENDER_ENUM.DATE_RANGE }, { name: "incidentDate", label: `${typeName}发生时间`, render: FORM_ITEM_RENDER_ENUM.DATE_RANGE },
]} ]}
@ -61,17 +64,21 @@ function Accident(props) {
rowSelection={{ rowSelection={{
selectedRowKeys, selectedRowKeys,
onChange: selectedRowKeys => setSelectedRowKeys(selectedRowKeys), onChange: selectedRowKeys => setSelectedRowKeys(selectedRowKeys),
preserveSelectedRowKeys: true,
}} }}
toolBarRender={() => ( toolBarRender={() => (
<Space> <Space>
<Button icon={<ExportIcon />} onClick={async () => { {props.permission(props.exportPermission) &&
const exportParams = getUrlCriteriaQuery("searchFormKeys","searchFormValues"); <Button loading={loading} icon={<ExportIcon />} onClick={async () => {
const exportParams = getUrlCriteriaQuery("searchFormKeys", "searchFormValues");
await downloadBlob("/accident/accident/export",{params:exportParams})
}}>导出</Button> await downloadBlob("/accident/accident/export", { params: {...exportParams, eqType: props.type} })
{!props.isSupervise && ( }}>导出</Button>
<React.Fragment> }
{!props.isSupervise && props.permission(props.addPermission) &&
<Button type="primary" icon={<AddIcon />} onClick={() => setAddModalVisible(true)}>新增</Button> <Button type="primary" icon={<AddIcon />} onClick={() => setAddModalVisible(true)}>新增</Button>
}
{!props.isSupervise && props.permission(props.deleteBatchPermission) &&
<Button icon={<DeleteIcon />} <Button icon={<DeleteIcon />}
type="primary" type="primary"
danger danger
@ -81,7 +88,7 @@ function Accident(props) {
Modal.confirm({ Modal.confirm({
title: "确定删除吗?", title: "确定删除吗?",
onOk: async () => { onOk: async () => {
await props["accidentBatchDelete"]({ ids: selectedRowKeys }); await props["accidentBatchDelete"]({ids: selectedRowKeys});
message.success("删除成功"); message.success("删除成功");
getData(); getData();
}, },
@ -90,8 +97,7 @@ function Accident(props) {
> >
批量删除 批量删除
</Button> </Button>
</React.Fragment> }
)}
</Space> </Space>
)} )}
columns={[ columns={[
@ -99,6 +105,8 @@ function Accident(props) {
{ dataIndex: "corpinfoName", title: `所属公司` }, { dataIndex: "corpinfoName", title: `所属公司` },
{ dataIndex: "incidentDate", title: `${typeName}发生时间` }, { dataIndex: "incidentDate", title: `${typeName}发生时间` },
{ dataIndex: "location", title: `${typeName}发生地点` }, { dataIndex: "location", title: `${typeName}发生地点` },
{ dataIndex: "incidentTypeName", title: `${typeName}类型`},
{ dataIndex: "incidentLevelName", title: `${typeName}等级`},
{ {
title: "操作", title: "操作",
align: "center", align: "center",
@ -115,7 +123,7 @@ function Accident(props) {
> >
查看 查看
</Button> </Button>
{!props.isSupervise && {!props.isSupervise && props.permission(props.editPermission) &&
<Button <Button
type="link" type="link"
onClick={() => { onClick={() => {
@ -127,7 +135,7 @@ function Accident(props) {
编辑 编辑
</Button> </Button>
} }
{!props.isSupervise && {!props.isSupervise && props.permission(props.deletePermission) &&
<Button <Button
type="link" type="link"
danger danger
@ -187,8 +195,8 @@ function AddModalComponent(props) {
// 文件相关状态和hooks // 文件相关状态和hooks
const [deleteImageFiles, setDeleteImageFiles] = useState([]); const [deleteImageFiles, setDeleteImageFiles] = useState([]);
const [deleteAttachmentFiles, setDeleteAttachmentFiles] = useState([]); const [deleteAttachmentFiles, setDeleteAttachmentFiles] = useState([]);
const { deleteFile } = useDeleteFile(); const { loading: deleteLoading, deleteFile } = useDeleteFile();
const { uploadFile } = useUploadFile(); const { loading: uploadLoading, uploadFile } = useUploadFile();
const { getFile } = useGetFile(); const { getFile } = useGetFile();
useEffect(() => { useEffect(() => {
@ -200,8 +208,8 @@ function AddModalComponent(props) {
const loadData = async () => { const loadData = async () => {
const { data } = await props["accidentInfo"]({ id: props.currentId }); const { data } = await props["accidentInfo"]({ id: props.currentId });
// 获取已上传的文件 // 获取已上传的文件
const imageFiles = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["136"], eqForeignKey: props.currentId }); const imageFiles = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["136"], eqForeignKey: data.accidentId });
const attachmentFiles = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["137"], eqForeignKey: props.currentId }); const attachmentFiles = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["137"], eqForeignKey: data.accidentId });
const values = { const values = {
...data, ...data,
@ -284,7 +292,6 @@ function AddModalComponent(props) {
message.success("操作成功"); message.success("操作成功");
} catch (error) { } catch (error) {
message.error("操作失败,请重试"); message.error("操作失败,请重试");
console.error("提交失败:", error);
} }
}; };
return ( return (
@ -293,7 +300,7 @@ function AddModalComponent(props) {
onCancel={onCancel} onCancel={onCancel}
onOk={form.submit} onOk={form.submit}
title={props.currentId ? "编辑" : "新增"} title={props.currentId ? "编辑" : "新增"}
loading={props.accident.accidentLoading} loading={props.accident.accidentLoading || uploadLoading || deleteLoading}
width={800} width={800}
> >
<FormBuilder <FormBuilder
@ -306,14 +313,14 @@ function AddModalComponent(props) {
{ name: "incidentNumber", label: `${typeName}案号` }, { name: "incidentNumber", label: `${typeName}案号` },
{ name: "incidentName", label: `${typeName}名称` }, { name: "incidentName", label: `${typeName}名称` },
{ name: "incidentType", label: `${typeName}类型`, render: <DictionarySelect dictValue="accidentType" onGetLabel={(label) => setDicNames({ ...dicNames, incidentTypeName: label })} /> }, { name: "incidentType", label: `${typeName}类型`, render: <DictionarySelect dictValue="accidentType" onGetLabel={(label) => setDicNames({ ...dicNames, incidentTypeName: label })} /> },
{ name: "incidentLevel", label: `${typeName}`, render: <DictionarySelect dictValue="accidentLevel" onGetLabel={(label) => setDicNames({ ...dicNames, incidentLevelName: label })} /> }, { name: "incidentLevel", label: `${typeName}`, render: <DictionarySelect dictValue="accidentLevel" onGetLabel={(label) => setDicNames({ ...dicNames, incidentLevelName: label })} /> },
{ name: "incidentNature", label: `${typeName}性质` }, { name: "incidentNature", label: `${typeName}性质` },
{ name: "location", label: `${typeName}发生地点` }, { name: "location", label: `${typeName}发生地点` },
{ name: "incidentDate", label: `${typeName}发生时间`, render: FORM_ITEM_RENDER_ENUM.DATETIME }, { name: "incidentDate", label: `${typeName}发生时间`, render: FORM_ITEM_RENDER_ENUM.DATETIME },
{ name: "directLoss", label: "直接经济损失(万元)", render: FORM_ITEM_RENDER_ENUM.NUMBER, rules: [{ pattern: TWO_DECIMAL_PLACES, message: "请保留2位小数" }] }, { name: "directLoss", label: "直接经济损失(万元)", render: FORM_ITEM_RENDER_ENUM.NUMBER,componentProps: { precision: 2,min: 0 }, required: false },
{ name: "injured", label: "受伤人数", render: FORM_ITEM_RENDER_ENUM.NUMBER }, { name: "injured", label: "受伤人数", render: FORM_ITEM_RENDER_ENUM.NUMBER,componentProps: { precision: 0,min: 0 }, required: false },
{ name: "fatalities", label: "死亡人数", render: FORM_ITEM_RENDER_ENUM.NUMBER }, { name: "fatalities", label: "死亡人数", render: FORM_ITEM_RENDER_ENUM.NUMBER,componentProps: { precision: 0,min: 0 }, required: false },
{ name: "seriouslyInjured", label: "重伤人数", render: FORM_ITEM_RENDER_ENUM.NUMBER }, { name: "seriouslyInjured", label: "重伤人数", render: FORM_ITEM_RENDER_ENUM.NUMBER,componentProps: { precision: 0,min: 0 }, required: false },
{ name: "cause", label: `${typeName}起因`, render: FORM_ITEM_RENDER_ENUM.TEXTAREA }, { name: "cause", label: `${typeName}起因`, render: FORM_ITEM_RENDER_ENUM.TEXTAREA },
{ name: "summary", label: `${typeName}概述`, render: FORM_ITEM_RENDER_ENUM.TEXTAREA }, { name: "summary", label: `${typeName}概述`, render: FORM_ITEM_RENDER_ENUM.TEXTAREA },
{ name: "analysis", label: "原因分析及责任认定", render: FORM_ITEM_RENDER_ENUM.TEXTAREA }, { name: "analysis", label: "原因分析及责任认定", render: FORM_ITEM_RENDER_ENUM.TEXTAREA },
@ -323,7 +330,7 @@ function AddModalComponent(props) {
// 添加图片上传 // 添加图片上传
{ {
name: "imageFiles", name: "imageFiles",
label: "事故图片", label: `${typeName}图片`,
render: ( render: (
<Upload <Upload
onGetRemoveFile={(file) => { onGetRemoveFile={(file) => {
@ -336,10 +343,11 @@ function AddModalComponent(props) {
// 添加附件上传 // 添加附件上传
{ {
name: "attachmentFiles", name: "attachmentFiles",
label: "事故附件", label: `${typeName}附件`,
required: false,
render: ( render: (
<Upload <Upload
fileType="file" fileType="document"
onGetRemoveFile={(file) => { onGetRemoveFile={(file) => {
setDeleteAttachmentFiles([...deleteAttachmentFiles, file]); setDeleteAttachmentFiles([...deleteAttachmentFiles, file]);
}} }}
@ -357,6 +365,7 @@ function InfoModalComponent(props) {
const [info, setInfo] = useState({}); const [info, setInfo] = useState({});
const [imageFiles, setImageFiles] = useState([]); const [imageFiles, setImageFiles] = useState([]);
const [attachmentFiles, setAttachmentFiles] = useState([]); const [attachmentFiles, setAttachmentFiles] = useState([]);
const { loading, downloadFile } = useDownloadFile()
const typeName = props.typeName; const typeName = props.typeName;
const { getFile } = useGetFile(); const { getFile } = useGetFile();
@ -373,8 +382,8 @@ function InfoModalComponent(props) {
setInfo(data); setInfo(data);
// 获取图片和附件 // 获取图片和附件
const images = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["136"], eqForeignKey: props.currentId }); const images = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["136"], eqForeignKey: data.accidentId });
const attachments = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["137"], eqForeignKey: props.currentId }); const attachments = await getFile({ eqType: UPLOAD_FILE_TYPE_ENUM["137"], eqForeignKey: data.accidentId });
setImageFiles(images); setImageFiles(images);
setAttachmentFiles(attachments); setAttachmentFiles(attachments);
@ -397,14 +406,14 @@ function InfoModalComponent(props) {
{ children: info.incidentNumber, label: `${typeName}案号` }, { children: info.incidentNumber, label: `${typeName}案号` },
{ children: info.incidentName, label: `${typeName}名称` }, { children: info.incidentName, label: `${typeName}名称` },
{ children: info.incidentTypeName, label: `${typeName}类型` }, { children: info.incidentTypeName, label: `${typeName}类型` },
{ children: info.incidentLevelName, label: `${typeName}` }, { children: info.incidentLevelName, label: `${typeName}` },
{ children: info.incidentNature, label: `${typeName}性质` }, { children: info.incidentNature, label: `${typeName}性质` },
{ children: info.location, label: `${typeName}发生地点` }, { children: info.location, label: `${typeName}发生地点` },
{ children: info.incidentDate, label: `${typeName}发生时间` }, { children: info.incidentDate, label: `${typeName}发生时间` },
{ children: info.directLoss, label: "直接经济损失(万元)" }, { children: info.directLoss || 0, label: "直接经济损失(万元)" },
{ children: info.injured, label: "受伤人数" }, { children: info.injured || 0, label: "受伤人数" },
{ children: info.fatalities, label: "死亡人数" }, { children: info.fatalities || 0, label: "死亡人数" },
{ children: info.seriouslyInjured, label: "重伤人数" }, { children: info.seriouslyInjured || 0, label: "重伤人数" },
{ children: info.cause, label: `${typeName}起因` }, { children: info.cause, label: `${typeName}起因` },
{ children: info.summary, label: `${typeName}概述` }, { children: info.summary, label: `${typeName}概述` },
{ children: info.analysis, label: "原因分析及责任认定" }, { children: info.analysis, label: "原因分析及责任认定" },
@ -413,29 +422,20 @@ function InfoModalComponent(props) {
{ children: info.reportDate, label: "报出日期" }, { children: info.reportDate, label: "报出日期" },
// 显示图片 // 显示图片
{ {
label: "事故图片", label: `${typeName}图片`,
children: ( children: (
<div> <PreviewImg files={imageFiles} />
{imageFiles.map((file, index) => (
<div key={index} style={{ marginBottom: 8 }}>
<a href={file.url} target="_blank" rel="noopener noreferrer">
{file.originalName}
</a>
</div>
))}
{imageFiles.length === 0 && <span></span>}
</div>
) )
}, },
// 显示附件 // 显示附件
{ {
label: "事故附件", label: `${typeName}附件`,
children: ( children: (
<div> <div>
{attachmentFiles.map((file, index) => ( {attachmentFiles.map((file, index) => (
<div key={index} style={{ marginBottom: 8 }}> <div key={index} style={{ marginBottom: 8 }}>
<a href={file.url} target="_blank" rel="noopener noreferrer"> <a onClick={() => downloadFile({ url: file.filePath, name: file.fileName })}>
{file.originalName} {file.fileName}
</a> </a>
</div> </div>
))} ))}
@ -451,4 +451,4 @@ function InfoModalComponent(props) {
const AddModal = Connect([NS_ACCIDENT], true)(AddModalComponent); const AddModal = Connect([NS_ACCIDENT], true)(AddModalComponent);
const InfoModal = Connect([NS_ACCIDENT], true)(InfoModalComponent); const InfoModal = Connect([NS_ACCIDENT], true)(InfoModalComponent);
export default Connect([NS_ACCIDENT], true)(Accident); export default Connect([NS_ACCIDENT], true)(Permission(Accident));

View File

@ -3,6 +3,11 @@ import Accident from "./components/Accident";
function AccidentContainer(props) { function AccidentContainer(props) {
return ( return (
<Accident type={2} <Accident type={2}
addPermission={"zcloud-accident-add"}
editPermission={"zcloud-accident-edit"}
deletePermission={"zcloud-accident-delete"}
deleteBatchPermission={"zcloud-accident-delete-batch"}
exportPermission={"zcloud-accident-export"}
{...props} {...props}
/> />
); );

View File

@ -3,6 +3,11 @@ import Accident from "../Accident/components/Accident";
function AccidentContainer(props) { function AccidentContainer(props) {
return ( return (
<Accident type={1} <Accident type={1}
addPermission={"zcloud-event-add"}
editPermission={"zcloud-event-edit"}
deletePermission={"zcloud-event-delete"}
deleteBatchPermission={"zcloud-event-delete-batch"}
exportPermission={"zcloud-event-export"}
{...props} {...props}
/> />
); );

View File

@ -7,6 +7,7 @@ function AccidentContainer(props) {
<Accident type={Number(eqAccidentType)} <Accident type={Number(eqAccidentType)}
isSupervise={true} isSupervise={true}
corpinfoId={corpinfoId} corpinfoId={corpinfoId}
exportPermission = { "zcloud-accident-supervise-export" }
{...props} {...props}
/> />
); );

View File

@ -35,6 +35,9 @@ function SuperviseAccident(props) {
const {tableProps, getData} = useTable(props["getCorpInfoList"], { const {tableProps, getData} = useTable(props["getCorpInfoList"], {
form, form,
params: {
inType: "0,1",
},
onSuccess: ({data}) => { onSuccess: ({data}) => {
getAccidentCountByCorpinfoAndType(data.map(item => item.id),form.getFieldValue("eqAccidentType")) getAccidentCountByCorpinfoAndType(data.map(item => item.id),form.getFieldValue("eqAccidentType"))
}, },