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

View File

@ -3,6 +3,11 @@ import Accident from "../Accident/components/Accident";
function AccidentContainer(props) {
return (
<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}
/>
);

View File

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

View File

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