1、修复bug
parent
6dad9b5b43
commit
8dd9cfddd7
|
|
@ -7,6 +7,7 @@ import "../blessed_by_buddha";
|
|||
|
||||
require("antd/dist/reset.css");
|
||||
require("zy-react-library/css/common.less");
|
||||
require("./styles/search-actions-right.less");
|
||||
|
||||
dayjs.locale("zh-cn");
|
||||
setJJBCommonAntdMessage(message);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Card, Col, Form, Input, InputNumber, message, Row, Space, Table } from "antd";
|
||||
import { Button, Card, Col, Form, Input, InputNumber, message, Row, Space } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import MapSelector from "zy-react-library/components/Map/MapSelector";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
|
|
@ -13,6 +13,20 @@ import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
|
|||
import useUploadFile from "zy-react-library/hooks/useUploadFile";
|
||||
import { NS_CONTROL_ROOM } from "~/enumerate/namespace";
|
||||
|
||||
// 手机号验证正则
|
||||
const MOBILE_PATTERN = /^1[3-9]\d{9}$/;
|
||||
|
||||
// 手机号验证函数
|
||||
const validatePhone = (rule, value) => {
|
||||
if (!value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (MOBILE_PATTERN.test(value)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error("请输入正确的手机号"));
|
||||
};
|
||||
|
||||
function Add(props) {
|
||||
const query = useGetUrlQuery();
|
||||
const [form] = Form.useForm();
|
||||
|
|
@ -22,10 +36,24 @@ function Add(props) {
|
|||
const [mapLng, setMapLng] = useState("");
|
||||
const [mapLat, setMapLat] = useState("");
|
||||
|
||||
// 设备信息列表
|
||||
const [deviceList, setDeviceList] = useState([]);
|
||||
// 人员信息列表
|
||||
const [personnelList, setPersonnelList] = useState([]);
|
||||
// 设备列表
|
||||
const createEmptyDevice = () => ({
|
||||
key: `${Date.now()}-${Math.random()}`,
|
||||
deviceName: "",
|
||||
deviceModel: "",
|
||||
deviceQty: undefined,
|
||||
deviceLocation: "",
|
||||
});
|
||||
const [devices, setDevices] = useState([createEmptyDevice()]);
|
||||
|
||||
// 人员列表
|
||||
const createEmptyPerson = () => ({
|
||||
key: `${Date.now()}-${Math.random()}`,
|
||||
personName: "",
|
||||
personPhone: "",
|
||||
dutyDesc: "",
|
||||
});
|
||||
const [persons, setPersons] = useState([createEmptyPerson()]);
|
||||
|
||||
// 文件上传相关hooks
|
||||
const { loading: uploadFileLoading, uploadFile } = useUploadFile();
|
||||
|
|
@ -53,12 +81,33 @@ function Add(props) {
|
|||
|
||||
// 设置设备列表
|
||||
if (data.devices && data.devices.length > 0) {
|
||||
setDeviceList(data.devices.map((item, index) => ({ ...item, key: item.id || index })));
|
||||
const deviceList = data.devices.map((item, index) => ({ ...item, key: item.id || index }));
|
||||
setDevices(deviceList);
|
||||
// 同步设置Form的设备数据
|
||||
form.setFieldValue('devicesForm', deviceList.map(d => ({
|
||||
deviceName: d.deviceName,
|
||||
deviceModel: d.deviceModel,
|
||||
deviceQty: d.deviceQty,
|
||||
deviceLocation: d.deviceLocation,
|
||||
})));
|
||||
}
|
||||
else {
|
||||
setDevices([createEmptyDevice()]);
|
||||
}
|
||||
|
||||
// 设置人员列表
|
||||
if (data.persons && data.persons.length > 0) {
|
||||
setPersonnelList(data.persons.map((item, index) => ({ ...item, key: item.id || index })));
|
||||
const personList = data.persons.map((item, index) => ({ ...item, key: item.id || index }));
|
||||
setPersons(personList);
|
||||
// 同步设置Form的人员数据
|
||||
form.setFieldValue('personsForm', personList.map(p => ({
|
||||
personName: p.personName,
|
||||
personPhone: p.personPhone,
|
||||
dutyDesc: p.dutyDesc,
|
||||
})));
|
||||
}
|
||||
else {
|
||||
setPersons([createEmptyPerson()]);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
|
|
@ -85,43 +134,67 @@ function Add(props) {
|
|||
setMapOpen(false);
|
||||
};
|
||||
|
||||
// 设备相关操作
|
||||
const addDevice = () => {
|
||||
const newDevices = [...devices, createEmptyDevice()];
|
||||
setDevices(newDevices);
|
||||
// 同步更新Form
|
||||
const formDevices = form.getFieldValue('devicesForm') || [];
|
||||
form.setFieldValue('devicesForm', [...formDevices, { deviceName: '', deviceModel: '', deviceQty: undefined, deviceLocation: '' }]);
|
||||
};
|
||||
|
||||
const removeDevice = (key) => {
|
||||
const index = devices.findIndex(item => item.key === key);
|
||||
const newDevices = devices.filter(item => item.key !== key);
|
||||
setDevices(newDevices);
|
||||
// 同步更新Form
|
||||
const formDevices = form.getFieldValue('devicesForm') || [];
|
||||
formDevices.splice(index, 1);
|
||||
form.setFieldValue('devicesForm', [...formDevices]);
|
||||
};
|
||||
|
||||
const updateDevice = (key, field, value) => {
|
||||
const index = devices.findIndex(item => item.key === key);
|
||||
setDevices(
|
||||
devices.map(item => (item.key === key ? { ...item, [field]: value } : item)),
|
||||
);
|
||||
// 同步更新Form并触发校验
|
||||
form.setFieldValue(['devicesForm', index, field], value);
|
||||
};
|
||||
|
||||
// 人员相关操作
|
||||
const addPerson = () => {
|
||||
const newPersons = [...persons, createEmptyPerson()];
|
||||
setPersons(newPersons);
|
||||
// 同步更新Form
|
||||
const formPersons = form.getFieldValue('personsForm') || [];
|
||||
form.setFieldValue('personsForm', [...formPersons, { personName: '', personPhone: '', dutyDesc: '' }]);
|
||||
};
|
||||
|
||||
const removePerson = (key) => {
|
||||
if (persons.length === 1) {
|
||||
message.warning("至少保留一条人员数据");
|
||||
return;
|
||||
}
|
||||
const index = persons.findIndex(item => item.key === key);
|
||||
const newPersons = persons.filter(item => item.key !== key);
|
||||
setPersons(newPersons);
|
||||
// 同步更新Form
|
||||
const formPersons = form.getFieldValue('personsForm') || [];
|
||||
formPersons.splice(index, 1);
|
||||
form.setFieldValue('personsForm', [...formPersons]);
|
||||
};
|
||||
|
||||
const updatePerson = (key, field, value) => {
|
||||
const index = persons.findIndex(item => item.key === key);
|
||||
setPersons(
|
||||
persons.map(item => (item.key === key ? { ...item, [field]: value } : item)),
|
||||
);
|
||||
// 同步更新Form并触发校验
|
||||
form.setFieldValue(['personsForm', index, field], value);
|
||||
};
|
||||
|
||||
const onFinish = async (values) => {
|
||||
// 验证设备列表
|
||||
if (deviceList.length === 0) {
|
||||
message.warning("请至少添加一条设备信息");
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证人员列表
|
||||
if (personnelList.length === 0) {
|
||||
message.warning("请至少添加一条人员信息");
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证设备列表是否填写完整
|
||||
const invalidDevice = deviceList.find(
|
||||
item => !item.deviceName || !item.deviceModel || !item.deviceQty || !item.deviceLocation,
|
||||
);
|
||||
if (invalidDevice) {
|
||||
message.warning("请完善设备信息");
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证人员列表是否填写完整
|
||||
const invalidPersonnel = personnelList.find(
|
||||
item => !item.personName || !item.personPhone,
|
||||
);
|
||||
if (invalidPersonnel) {
|
||||
message.warning("请完善人员信息");
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证图片是否上传
|
||||
if (!values.roomImages || values.roomImages.length === 0) {
|
||||
message.warning("请上传消防控制室图片");
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
try {
|
||||
// 先删除标记删除的文件
|
||||
|
|
@ -129,36 +202,42 @@ function Add(props) {
|
|||
await deleteFile({ single: false, files: deleteFiles });
|
||||
}
|
||||
|
||||
// 上传图片文件,获取业务ID(room_id)
|
||||
const { id: roomId } = await uploadFile({
|
||||
single: false,
|
||||
files: values.roomImages,
|
||||
params: {
|
||||
type: UPLOAD_FILE_TYPE_ENUM[302],
|
||||
foreignKey: values.roomId,
|
||||
},
|
||||
});
|
||||
let roomId = values.roomId;
|
||||
if (values.roomImages && values.roomImages.length > 0) {
|
||||
// 上传图片文件,获取业务ID(room_id)
|
||||
const { id: uploadedRoomId } = await uploadFile({
|
||||
single: false,
|
||||
files: values.roomImages,
|
||||
params: {
|
||||
type: UPLOAD_FILE_TYPE_ENUM[302],
|
||||
foreignKey: values.roomId,
|
||||
},
|
||||
});
|
||||
roomId = uploadedRoomId;
|
||||
}
|
||||
|
||||
const apiMethod = query.id ? props["controlRoomUpdate"] : props["controlRoomAdd"];
|
||||
|
||||
// 构建提交参数
|
||||
// 过滤掉空的设备信息
|
||||
const validDevices = devices.filter(
|
||||
device => device.deviceName || device.deviceModel || device.deviceQty || device.deviceLocation,
|
||||
);
|
||||
|
||||
const params = {
|
||||
...values,
|
||||
roomId,
|
||||
// 设备列表:去掉前端添加的 key
|
||||
devices: deviceList.map(({ key, ...device }) => ({
|
||||
devices: validDevices.map(({ key, ...device }) => ({
|
||||
deviceName: device.deviceName,
|
||||
deviceModel: device.deviceModel,
|
||||
deviceQty: device.deviceQty,
|
||||
deviceLocation: device.deviceLocation,
|
||||
...(device.id && { id: device.id }),
|
||||
})),
|
||||
// 人员列表:去掉前端添加的 key
|
||||
persons: personnelList.map(({ key, ...personnel }) => ({
|
||||
personName: personnel.personName,
|
||||
personPhone: personnel.personPhone,
|
||||
dutyDesc: personnel.dutyDesc || "",
|
||||
...(personnel.id && { id: personnel.id }),
|
||||
persons: persons.map(({ key, ...person }) => ({
|
||||
personName: person.personName,
|
||||
personPhone: person.personPhone,
|
||||
dutyDesc: person.dutyDesc,
|
||||
...(person.id && { id: person.id }),
|
||||
})),
|
||||
};
|
||||
|
||||
|
|
@ -179,189 +258,19 @@ function Add(props) {
|
|||
}
|
||||
};
|
||||
|
||||
// 设备列表相关操作
|
||||
const addDevice = () => {
|
||||
const newDevice = {
|
||||
key: Date.now(),
|
||||
deviceName: "",
|
||||
deviceModel: "",
|
||||
deviceQty: null,
|
||||
deviceLocation: "",
|
||||
};
|
||||
setDeviceList([...deviceList, newDevice]);
|
||||
};
|
||||
|
||||
const removeDevice = (key) => {
|
||||
setDeviceList(deviceList.filter(item => item.key !== key));
|
||||
};
|
||||
|
||||
const updateDevice = (key, field, value) => {
|
||||
setDeviceList(
|
||||
deviceList.map(item => (item.key === key ? { ...item, [field]: value } : item)),
|
||||
);
|
||||
};
|
||||
|
||||
// 人员列表相关操作
|
||||
const addPersonnel = () => {
|
||||
const newPersonnel = {
|
||||
key: Date.now(),
|
||||
personName: "",
|
||||
personPhone: "",
|
||||
dutyDesc: "",
|
||||
};
|
||||
setPersonnelList([...personnelList, newPersonnel]);
|
||||
};
|
||||
|
||||
const removePersonnel = (key) => {
|
||||
setPersonnelList(personnelList.filter(item => item.key !== key));
|
||||
};
|
||||
|
||||
const updatePersonnel = (key, field, value) => {
|
||||
setPersonnelList(
|
||||
personnelList.map(item => (item.key === key ? { ...item, [field]: value } : item)),
|
||||
);
|
||||
};
|
||||
|
||||
// 设备表格列定义
|
||||
const deviceColumns = [
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
设备名称
|
||||
</>),
|
||||
dataIndex: "deviceName",
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入设备名称"
|
||||
onChange={e => updateDevice(record.key, "deviceName", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
设备型号
|
||||
</>),
|
||||
dataIndex: "deviceModel",
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入设备型号"
|
||||
onChange={e => updateDevice(record.key, "deviceModel", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
设备数量
|
||||
</>),
|
||||
dataIndex: "deviceQty",
|
||||
render: (text, record) => (
|
||||
<InputNumber
|
||||
value={text}
|
||||
placeholder="请输入设备数量"
|
||||
min={1}
|
||||
style={{ width: "100%" }}
|
||||
onChange={value => updateDevice(record.key, "deviceQty", value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
设备位置
|
||||
</>),
|
||||
dataIndex: "deviceLocation",
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入设备位置"
|
||||
onChange={e => updateDevice(record.key, "deviceLocation", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 80,
|
||||
align: "center",
|
||||
render: (_, record) => (
|
||||
<Button type="link" danger onClick={() => removeDevice(record.key)}>
|
||||
删除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
// 人员表格列定义
|
||||
const personnelColumns = [
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
人员姓名
|
||||
</>),
|
||||
dataIndex: "personName",
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入人员姓名"
|
||||
onChange={e => updatePersonnel(record.key, "personName", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
人员手机号
|
||||
</>),
|
||||
dataIndex: "personPhone",
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入人员手机号"
|
||||
maxLength={11}
|
||||
onChange={e => updatePersonnel(record.key, "personPhone", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "人员值班情况",
|
||||
dataIndex: "dutyDesc",
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入人员值班情况"
|
||||
onChange={e => updatePersonnel(record.key, "dutyDesc", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 80,
|
||||
align: "center",
|
||||
render: (_, record) => (
|
||||
<Button type="link" danger onClick={() => removePersonnel(record.key)}>
|
||||
删除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Page
|
||||
headerTitle={query.id ? "编辑消防控制室" : "新增消防控制室"}
|
||||
loading={loading || uploadFileLoading || deleteFileLoading || getFileLoading}
|
||||
isShowFooter={false}
|
||||
isShowBack={false}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
onFinish={onFinish}
|
||||
style={{ maxWidth: 1200, margin: "24px auto" }}
|
||||
>
|
||||
<Card title="基本信息" style={{ marginBottom: 24 }}>
|
||||
<Card title="基本信息" bordered={false} style={{ boxShadow: 'none' }}>
|
||||
{/* 添加隐藏字段保存 roomId */}
|
||||
<Form.Item name="roomId" hidden>
|
||||
<Input />
|
||||
|
|
@ -374,7 +283,7 @@ function Add(props) {
|
|||
name="roomName"
|
||||
rules={[
|
||||
{ required: true, message: "请输入消防控制室名称" },
|
||||
{ max: 100, message: "消防控制室名称不能超过100个字符" },
|
||||
{ max: 50, message: "消防控制室名称不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入消防控制室名称" />
|
||||
|
|
@ -415,10 +324,17 @@ function Add(props) {
|
|||
name="principalPhone"
|
||||
rules={[
|
||||
{ required: true, message: "请输入负责人手机号" },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号" },
|
||||
{ validator: validatePhone },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入负责人手机号" maxLength={11} />
|
||||
<Input
|
||||
placeholder="请输入负责人手机号"
|
||||
maxLength={11}
|
||||
onChange={e => {
|
||||
const value = e.target.value.replace(/\D/g, '');
|
||||
form.setFieldValue('principalPhone', value);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
@ -437,7 +353,7 @@ function Add(props) {
|
|||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="纬度"
|
||||
required
|
||||
rules={[{ required: true, message: "请选择纬度" }]}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item
|
||||
|
|
@ -462,14 +378,14 @@ function Add(props) {
|
|||
name="roomImages"
|
||||
labelCol={{ span: 3 }}
|
||||
wrapperCol={{ span: 21 }}
|
||||
rules={[{ required: true, message: "请上传消防控制室图片" }]}
|
||||
extra="默认上传4个,目前支持jpg、jpeg、png格式,单张图片不超过5mb"
|
||||
>
|
||||
<Upload
|
||||
fileType="image"
|
||||
maxCount={4}
|
||||
maxSize={5}
|
||||
size={5}
|
||||
accept=".jpg,.jpeg,.png"
|
||||
tipContent="默认上限4个,且只支持jpg、jpeg、png格式,单张且不超过5mb"
|
||||
listType="picture-card"
|
||||
onGetRemoveFile={(file) => {
|
||||
setDeleteFiles([...deleteFiles, file]);
|
||||
}}
|
||||
|
|
@ -481,41 +397,173 @@ function Add(props) {
|
|||
|
||||
<Card
|
||||
title="设备信息"
|
||||
style={{ marginTop: 24, boxShadow: 'none' }}
|
||||
bordered={false}
|
||||
extra={(
|
||||
<Button type="primary" onClick={addDevice}>
|
||||
新增
|
||||
</Button>
|
||||
)}
|
||||
style={{ marginBottom: 24 }}
|
||||
>
|
||||
<Table
|
||||
columns={deviceColumns}
|
||||
dataSource={deviceList}
|
||||
pagination={false}
|
||||
rowKey="key"
|
||||
locale={{ emptyText: "暂无设备信息,请点击新增按钮添加" }}
|
||||
/>
|
||||
{devices.map((device, index) => (
|
||||
<div key={device.key} style={{ marginBottom: 16 }}>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="设备名称"
|
||||
name={['devicesForm', index, 'deviceName']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入设备名称" },
|
||||
{ max: 50, message: "设备名称不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入设备名称"
|
||||
onChange={e => updateDevice(device.key, "deviceName", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="设备型号"
|
||||
name={['devicesForm', index, 'deviceModel']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入设备型号" },
|
||||
{ max: 50, message: "设备型号不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入设备型号"
|
||||
onChange={e => updateDevice(device.key, "deviceModel", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="设备数量"
|
||||
name={['devicesForm', index, 'deviceQty']}
|
||||
rules={[{ required: true, message: "请输入设备数量" }]}
|
||||
>
|
||||
<InputNumber
|
||||
placeholder="请输入设备数量"
|
||||
min={1}
|
||||
style={{ width: "100%" }}
|
||||
onChange={value => updateDevice(device.key, "deviceQty", value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="设备位置"
|
||||
required
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item
|
||||
name={['devicesForm', index, 'deviceLocation']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入设备位置" },
|
||||
{ max: 50, message: "设备位置不能超过50个字符" },
|
||||
]}
|
||||
noStyle
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入设备位置"
|
||||
onChange={e => updateDevice(device.key, "deviceLocation", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Button danger onClick={() => removeDevice(device.key)}>
|
||||
删除
|
||||
</Button>
|
||||
</Space.Compact>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
))}
|
||||
</Card>
|
||||
|
||||
<Card
|
||||
title="人员信息"
|
||||
style={{ marginTop: 24, boxShadow: 'none' }}
|
||||
bordered={false}
|
||||
extra={(
|
||||
<Button type="primary" onClick={addPersonnel}>
|
||||
<Button type="primary" onClick={addPerson}>
|
||||
新增
|
||||
</Button>
|
||||
)}
|
||||
style={{ marginBottom: 24 }}
|
||||
>
|
||||
<Table
|
||||
columns={personnelColumns}
|
||||
dataSource={personnelList}
|
||||
pagination={false}
|
||||
rowKey="key"
|
||||
locale={{ emptyText: "暂无人员信息,请点击新增按钮添加" }}
|
||||
/>
|
||||
{persons.map((person, index) => (
|
||||
<div key={person.key} style={{ marginBottom: 16 }}>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="人员姓名"
|
||||
name={['personsForm', index, 'personName']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入人员姓名" },
|
||||
{ max: 50, message: "人员姓名不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入人员姓名"
|
||||
onChange={e => updatePerson(person.key, "personName", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="人员手机号"
|
||||
name={['personsForm', index, 'personPhone']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入人员手机号" },
|
||||
{ validator: validatePhone },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入人员手机号"
|
||||
maxLength={11}
|
||||
onChange={e => {
|
||||
const value = e.target.value.replace(/\D/g, '');
|
||||
updatePerson(person.key, "personPhone", value);
|
||||
form.setFieldValue(['personsForm', index, 'personPhone'], value);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="人员值班情况"
|
||||
name={['personsForm', index, 'dutyDesc']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入人员值班情况" },
|
||||
{ max: 50, message: "人员值班情况不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入人员值班情况"
|
||||
onChange={e => updatePerson(person.key, "dutyDesc", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div style={{ textAlign: 'right', paddingTop: 30 }}>
|
||||
{index > 0 && (
|
||||
<Button danger onClick={() => removePerson(person.key)}>
|
||||
删除
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
))}
|
||||
</Card>
|
||||
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "center" }}>
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "center", marginTop: 24 }}>
|
||||
<Space size={16}>
|
||||
<Button onClick={() => props.history.goBack()}>
|
||||
取消
|
||||
|
|
|
|||
|
|
@ -14,8 +14,47 @@ import { NS_CONTROL_ROOM } from "~/enumerate/namespace";
|
|||
function List(props) {
|
||||
const [form] = Form.useForm();
|
||||
const query = useGetUrlQuery();
|
||||
const normalizeBackPath = (path) => {
|
||||
if (!path)
|
||||
return "";
|
||||
try {
|
||||
const url = new URL(path, window.location.origin);
|
||||
const appPrefix = `/${window.process?.env?.appIdentifier || "fireResource"}`;
|
||||
let pathname = url.pathname;
|
||||
if (pathname.startsWith(`${appPrefix}/`))
|
||||
pathname = pathname.slice(appPrefix.length);
|
||||
else if (pathname === appPrefix)
|
||||
pathname = "/";
|
||||
return `${pathname}${url.search}`;
|
||||
}
|
||||
catch (error) {
|
||||
return path;
|
||||
}
|
||||
};
|
||||
const isFromSupervision = !!query.eqCorpId;
|
||||
const supervisionBackPath = normalizeBackPath(query.backPath
|
||||
|| props.location?.state?.backPath
|
||||
|| window.sessionStorage.getItem("supervisionFireResourceStatsBackPath")
|
||||
|| "");
|
||||
const pageHistory = isFromSupervision
|
||||
? {
|
||||
...props.history,
|
||||
goBack: () => {
|
||||
if (supervisionBackPath) {
|
||||
props.history.push(supervisionBackPath);
|
||||
return true;
|
||||
}
|
||||
window.history.back();
|
||||
return true;
|
||||
},
|
||||
}
|
||||
: props.history;
|
||||
|
||||
const { tableProps, getData } = useTable(props["controlRoomList"], { form });
|
||||
const { tableProps, getData } = useTable(props["controlRoomList"], {
|
||||
form,
|
||||
params: () => (query.eqCorpId ? { eqCorpId: query.eqCorpId } : {}),
|
||||
});
|
||||
const handleSearch = values => getData(query.eqCorpId ? { ...values, eqCorpId: query.eqCorpId } : values);
|
||||
|
||||
const [deleting, setDeleting] = useState(false);
|
||||
const [statusDict, setStatusDict] = useState([]);
|
||||
|
|
@ -96,7 +135,11 @@ function List(props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Page
|
||||
isShowAllAction={isFromSupervision}
|
||||
isShowFooter={false}
|
||||
history={pageHistory}
|
||||
>
|
||||
<Search
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
|
|
@ -116,7 +159,8 @@ function List(props) {
|
|||
},
|
||||
]}
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
values={query.eqCorpId ? { eqCorpId: query.eqCorpId } : {}}
|
||||
onFinish={handleSearch}
|
||||
/>
|
||||
|
||||
<Table
|
||||
|
|
|
|||
|
|
@ -93,14 +93,13 @@ function View(props) {
|
|||
const deviceColumns = [
|
||||
{
|
||||
title: "序号",
|
||||
width: 80,
|
||||
width: 150,
|
||||
align: "center",
|
||||
render: (_, __, index) => index + 1,
|
||||
},
|
||||
{
|
||||
title: "设备名称",
|
||||
dataIndex: "deviceName",
|
||||
width: 180,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -108,7 +107,6 @@ function View(props) {
|
|||
{
|
||||
title: "设备型号",
|
||||
dataIndex: "deviceModel",
|
||||
width: 180,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -116,7 +114,6 @@ function View(props) {
|
|||
{
|
||||
title: "设备数量",
|
||||
dataIndex: "deviceQty",
|
||||
width: 120,
|
||||
align: "center",
|
||||
render: text => text || 0,
|
||||
},
|
||||
|
|
@ -133,14 +130,14 @@ function View(props) {
|
|||
const personnelColumns = [
|
||||
{
|
||||
title: "序号",
|
||||
width: 80,
|
||||
width: 150,
|
||||
align: "center",
|
||||
render: (_, __, index) => index + 1,
|
||||
},
|
||||
{
|
||||
title: "人员姓名",
|
||||
dataIndex: "personName",
|
||||
width: 160,
|
||||
width: 420,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -148,7 +145,7 @@ function View(props) {
|
|||
{
|
||||
title: "人员手机号",
|
||||
dataIndex: "personPhone",
|
||||
width: 180,
|
||||
width: 420,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -164,13 +161,13 @@ function View(props) {
|
|||
|
||||
return (
|
||||
<Page
|
||||
headerTitle="查看消防控制室"
|
||||
loading={loading || dictLoading || getFileLoading}
|
||||
isShowFooter={false}
|
||||
isShowBack={false}
|
||||
>
|
||||
{detail && (
|
||||
<div style={{ maxWidth: 1200, margin: "24px auto" }}>
|
||||
<Card title="基本信息" style={{ marginBottom: 24 }}>
|
||||
<div>
|
||||
<Card title="基本信息" bordered={false} style={{ boxShadow: 'none' }}>
|
||||
<Descriptions
|
||||
bordered
|
||||
column={2}
|
||||
|
|
@ -218,8 +215,9 @@ function View(props) {
|
|||
/>
|
||||
</Card>
|
||||
|
||||
<Card title="设备信息" style={{ marginBottom: 24 }}>
|
||||
<Card title="设备信息" style={{ marginTop: 24, boxShadow: 'none' }} bordered={false}>
|
||||
<Table
|
||||
bordered
|
||||
columns={deviceColumns}
|
||||
dataSource={detail.devices || []}
|
||||
pagination={false}
|
||||
|
|
@ -228,8 +226,9 @@ function View(props) {
|
|||
/>
|
||||
</Card>
|
||||
|
||||
<Card title="人员信息" style={{ marginBottom: 24 }}>
|
||||
<Card title="人员信息" style={{ marginTop: 24, boxShadow: 'none' }} bordered={false}>
|
||||
<Table
|
||||
bordered
|
||||
columns={personnelColumns}
|
||||
dataSource={detail.persons || []}
|
||||
pagination={false}
|
||||
|
|
@ -238,7 +237,7 @@ function View(props) {
|
|||
/>
|
||||
</Card>
|
||||
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<div style={{ textAlign: "center", marginTop: 24 }}>
|
||||
<Button onClick={() => props.history.goBack()}>
|
||||
返回
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ function FireResourceStats(props) {
|
|||
align: "center",
|
||||
render: (text, record) => (
|
||||
<a
|
||||
style={{ color: "#1677ff", fontWeight: 600, textDecoration: "underline" }}
|
||||
style={{ color: "#1677ff", WebkitTextFillColor: "#1677ff", fontWeight: 600 }}
|
||||
onClick={() => handleViewDetail(record, "rescueTeam")}
|
||||
>
|
||||
{text || 0}
|
||||
|
|
@ -66,7 +66,7 @@ function FireResourceStats(props) {
|
|||
align: "center",
|
||||
render: (text, record) => (
|
||||
<a
|
||||
style={{ color: "#1677ff", fontWeight: 600, textDecoration: "underline" }}
|
||||
style={{ color: "#1677ff", WebkitTextFillColor: "#1677ff", fontWeight: 600 }}
|
||||
onClick={() => handleViewDetail(record, "controlRoom")}
|
||||
>
|
||||
{text || 0}
|
||||
|
|
@ -80,7 +80,7 @@ function FireResourceStats(props) {
|
|||
align: "center",
|
||||
render: (text, record) => (
|
||||
<a
|
||||
style={{ color: "#1677ff", fontWeight: 600, textDecoration: "underline" }}
|
||||
style={{ color: "#1677ff", WebkitTextFillColor: "#1677ff", fontWeight: 600 }}
|
||||
onClick={() => handleViewDetail(record, "pumpRoom")}
|
||||
>
|
||||
{text || 0}
|
||||
|
|
@ -94,7 +94,7 @@ function FireResourceStats(props) {
|
|||
align: "center",
|
||||
render: (text, record) => (
|
||||
<a
|
||||
style={{ color: "#1677ff", fontWeight: 600, textDecoration: "underline" }}
|
||||
style={{ color: "#1677ff", WebkitTextFillColor: "#1677ff", fontWeight: 600 }}
|
||||
onClick={() => handleViewDetail(record, "waterSource")}
|
||||
>
|
||||
{text || 0}
|
||||
|
|
@ -109,3 +109,4 @@ function FireResourceStats(props) {
|
|||
}
|
||||
|
||||
export default Connect([NS_FIRE_RESOURCE_STATS], true)(Permission(FireResourceStats));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Card, Col, Form, Input, message, Row, Space, Table } from "antd";
|
||||
import { Button, Card, Col, Form, Input, message, Row, Space } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import MapSelector from "zy-react-library/components/Map/MapSelector";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
|
|
@ -13,6 +13,20 @@ import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
|
|||
import useUploadFile from "zy-react-library/hooks/useUploadFile";
|
||||
import { NS_PUMP_ROOM } from "~/enumerate/namespace";
|
||||
|
||||
// 手机号验证正则
|
||||
const MOBILE_PATTERN = /^1[3-9]\d{9}$/;
|
||||
|
||||
// 手机号验证函数
|
||||
const validatePhone = (rule, value) => {
|
||||
if (!value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (MOBILE_PATTERN.test(value)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error("请输入正确的手机号"));
|
||||
};
|
||||
|
||||
function Add(props) {
|
||||
const query = useGetUrlQuery();
|
||||
const [form] = Form.useForm();
|
||||
|
|
@ -23,7 +37,16 @@ function Add(props) {
|
|||
const [mapLat, setMapLat] = useState("");
|
||||
|
||||
// 设备信息列表
|
||||
const [devices, setDeviceList] = useState([]);
|
||||
const createEmptyDevice = () => ({
|
||||
key: `${Date.now()}-${Math.random()}`,
|
||||
deviceCode: "",
|
||||
deviceName: "",
|
||||
deviceCategory: "",
|
||||
chargeUnit: "",
|
||||
deviceLocation: "",
|
||||
paramsSpec: "",
|
||||
});
|
||||
const [devices, setDeviceList] = useState([createEmptyDevice()]);
|
||||
|
||||
const { loading: uploadFileLoading, uploadFile } = useUploadFile();
|
||||
const { loading: deleteFileLoading, deleteFile } = useDeleteFile();
|
||||
|
|
@ -47,7 +70,19 @@ function Add(props) {
|
|||
|
||||
// 设置设备列表
|
||||
if (data.devices && data.devices.length > 0) {
|
||||
setDeviceList(data.devices.map((item, index) => ({ ...item, key: item.id || index })));
|
||||
const deviceList = data.devices.map((item, index) => ({ ...item, key: item.id || index }));
|
||||
setDeviceList(deviceList);
|
||||
// 同步设置Form的设备数据
|
||||
form.setFieldValue('devicesForm', deviceList.map(d => ({
|
||||
deviceCode: d.deviceCode,
|
||||
deviceName: d.deviceName,
|
||||
deviceCategory: d.deviceCategory,
|
||||
chargeUnit: d.chargeUnit,
|
||||
deviceLocation: d.deviceLocation,
|
||||
paramsSpec: d.paramsSpec,
|
||||
})));
|
||||
} else {
|
||||
setDeviceList([createEmptyDevice()]);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
|
|
@ -74,48 +109,37 @@ function Add(props) {
|
|||
};
|
||||
|
||||
const onFinish = async (values) => {
|
||||
// 验证设备列表
|
||||
if (devices.length === 0) {
|
||||
message.warning("请至少添加一条设备信息");
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证设备列表是否填写完整
|
||||
const invalidDevice = devices.find(
|
||||
item => !item.deviceCode || !item.deviceName || !item.deviceCategory
|
||||
|| !item.chargeUnit || !item.deviceLocation || !item.paramsSpec,
|
||||
);
|
||||
if (invalidDevice) {
|
||||
message.warning("请完善设备信息");
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证图片是否上传
|
||||
if (!values.roomImages || values.roomImages.length === 0) {
|
||||
message.warning("请上传消防泵房图片");
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
try {
|
||||
if (deleteFiles.length > 0) {
|
||||
await deleteFile({ single: false, files: deleteFiles });
|
||||
}
|
||||
|
||||
const { id: pumpRoomId } = await uploadFile({
|
||||
single: false,
|
||||
files: values.roomImages,
|
||||
params: {
|
||||
type: UPLOAD_FILE_TYPE_ENUM[302],
|
||||
foreignKey: values.roomId || values.pumpRoomId || query.id,
|
||||
},
|
||||
});
|
||||
let pumpRoomId = values.pumpRoomId || values.roomId || query.id;
|
||||
if (values.roomImages && values.roomImages.length > 0) {
|
||||
const { id: uploadedPumpRoomId } = await uploadFile({
|
||||
single: false,
|
||||
files: values.roomImages,
|
||||
params: {
|
||||
type: UPLOAD_FILE_TYPE_ENUM[302],
|
||||
foreignKey: values.roomId || values.pumpRoomId || query.id,
|
||||
},
|
||||
});
|
||||
pumpRoomId = uploadedPumpRoomId;
|
||||
}
|
||||
|
||||
const apiMethod = query.id ? props["pumpRoomUpdate"] : props["pumpRoomAdd"];
|
||||
|
||||
// 过滤掉空的设备信息
|
||||
const validDevices = devices.filter(
|
||||
device => device.deviceCode || device.deviceName || device.deviceCategory ||
|
||||
device.chargeUnit || device.deviceLocation || device.paramsSpec,
|
||||
);
|
||||
|
||||
const params = {
|
||||
...values,
|
||||
pumpRoomId,
|
||||
devices: devices.map(({ key, ...device }) => ({
|
||||
devices: validDevices.map(({ key, ...device }) => ({
|
||||
deviceCode: device.deviceCode,
|
||||
deviceName: device.deviceName,
|
||||
deviceCategory: device.deviceCategory,
|
||||
|
|
@ -143,146 +167,52 @@ function Add(props) {
|
|||
|
||||
// 设备列表相关操作
|
||||
const addDevice = () => {
|
||||
const newDevice = {
|
||||
key: Date.now(),
|
||||
deviceCode: "",
|
||||
deviceName: "",
|
||||
deviceCategory: "",
|
||||
chargeUnit: "",
|
||||
deviceLocation: "",
|
||||
paramsSpec: "",
|
||||
};
|
||||
setDeviceList([...devices, newDevice]);
|
||||
const newDevices = [...devices, createEmptyDevice()];
|
||||
setDeviceList(newDevices);
|
||||
// 同步更新Form
|
||||
const formDevices = form.getFieldValue('devicesForm') || [];
|
||||
form.setFieldValue('devicesForm', [...formDevices, {
|
||||
deviceCode: '',
|
||||
deviceName: '',
|
||||
deviceCategory: '',
|
||||
chargeUnit: '',
|
||||
deviceLocation: '',
|
||||
paramsSpec: ''
|
||||
}]);
|
||||
};
|
||||
|
||||
const removeDevice = (key) => {
|
||||
setDeviceList(devices.filter(item => item.key !== key));
|
||||
const index = devices.findIndex(item => item.key === key);
|
||||
const newDevices = devices.filter(item => item.key !== key);
|
||||
setDeviceList(newDevices);
|
||||
// 同步更新Form
|
||||
const formDevices = form.getFieldValue('devicesForm') || [];
|
||||
formDevices.splice(index, 1);
|
||||
form.setFieldValue('devicesForm', [...formDevices]);
|
||||
};
|
||||
|
||||
const updateDevice = (key, field, value) => {
|
||||
const index = devices.findIndex(item => item.key === key);
|
||||
setDeviceList(
|
||||
devices.map(item => (item.key === key ? { ...item, [field]: value } : item)),
|
||||
);
|
||||
// 同步更新Form并触发校验
|
||||
form.setFieldValue(['devicesForm', index, field], value);
|
||||
};
|
||||
|
||||
// 设备表格列定义
|
||||
const deviceColumns = [
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
设备编号
|
||||
</>),
|
||||
dataIndex: "deviceCode",
|
||||
width: 150,
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入设备编号"
|
||||
onChange={e => updateDevice(record.key, "deviceCode", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
设备名称
|
||||
</>),
|
||||
dataIndex: "deviceName",
|
||||
width: 150,
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入设备名称"
|
||||
onChange={e => updateDevice(record.key, "deviceName", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
设备分类
|
||||
</>),
|
||||
dataIndex: "deviceCategory",
|
||||
width: 150,
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入设备分类"
|
||||
onChange={e => updateDevice(record.key, "deviceCategory", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
负责单位
|
||||
</>),
|
||||
dataIndex: "chargeUnit",
|
||||
width: 150,
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入负责单位"
|
||||
onChange={e => updateDevice(record.key, "chargeUnit", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
具体位置
|
||||
</>),
|
||||
dataIndex: "deviceLocation",
|
||||
width: 150,
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入具体位置"
|
||||
onChange={e => updateDevice(record.key, "deviceLocation", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
设备参数和规格
|
||||
</>),
|
||||
dataIndex: "paramsSpec",
|
||||
width: 180,
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入设备参数和规格"
|
||||
onChange={e => updateDevice(record.key, "paramsSpec", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 100,
|
||||
align: "center",
|
||||
render: (_, record) => (
|
||||
<Button type="link" danger onClick={() => removeDevice(record.key)}>
|
||||
删除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Page
|
||||
headerTitle={query.id ? "编辑消防泵房" : "新增消防泵房"}
|
||||
loading={loading || uploadFileLoading || deleteFileLoading || getFileLoading}
|
||||
isShowFooter={false}
|
||||
isShowBack={false}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
onFinish={onFinish}
|
||||
style={{ maxWidth: 1200, margin: "24px auto" }}
|
||||
>
|
||||
<Card title="基本信息" style={{ marginBottom: 24 }}>
|
||||
<Card title="基本信息" bordered={false} style={{ boxShadow: 'none' }}>
|
||||
<Form.Item name="pumpRoomId" hidden>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
|
@ -294,7 +224,7 @@ function Add(props) {
|
|||
name="pumpRoomName"
|
||||
rules={[
|
||||
{ required: true, message: "请输入消防泵房名称" },
|
||||
{ max: 100, message: "消防泵房名称不能超过100个字符" },
|
||||
{ max: 50, message: "消防泵房名称不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入消防泵房名称" />
|
||||
|
|
@ -335,10 +265,17 @@ function Add(props) {
|
|||
name="principalPhone"
|
||||
rules={[
|
||||
{ required: true, message: "请输入负责人手机号" },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号" },
|
||||
{ validator: validatePhone },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入负责人手机号" maxLength={11} />
|
||||
<Input
|
||||
placeholder="请输入负责人手机号"
|
||||
maxLength={11}
|
||||
onChange={e => {
|
||||
const value = e.target.value.replace(/\D/g, '');
|
||||
form.setFieldValue('principalPhone', value);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
@ -357,7 +294,7 @@ function Add(props) {
|
|||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="纬度"
|
||||
required
|
||||
rules={[{ required: true, message: "请选择纬度" }]}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item
|
||||
|
|
@ -382,14 +319,13 @@ function Add(props) {
|
|||
name="roomImages"
|
||||
labelCol={{ span: 3 }}
|
||||
wrapperCol={{ span: 21 }}
|
||||
rules={[{ required: true, message: "请上传消防泵房图片" }]}
|
||||
extra="默认上传4个,目前支持jpg、jpeg、png格式,单张图片不超过5mb"
|
||||
>
|
||||
<Upload
|
||||
fileType="image"
|
||||
maxCount={4}
|
||||
maxSize={5}
|
||||
size={5}
|
||||
accept=".jpg,.jpeg,.png"
|
||||
tipContent="默认上限4个,且只支持jpg、jpeg、png格式,单张且不超过5mb"
|
||||
onGetRemoveFile={(file) => {
|
||||
setDeleteFiles([...deleteFiles, file]);
|
||||
}}
|
||||
|
|
@ -406,18 +342,122 @@ function Add(props) {
|
|||
新增
|
||||
</Button>
|
||||
)}
|
||||
style={{ marginBottom: 24 }}
|
||||
style={{ marginTop: 24, boxShadow: 'none' }}
|
||||
bordered={false}
|
||||
>
|
||||
<Table
|
||||
columns={deviceColumns}
|
||||
dataSource={devices}
|
||||
pagination={false}
|
||||
rowKey="key"
|
||||
locale={{ emptyText: "暂无设备信息,请点击新增按钮添加" }}
|
||||
/>
|
||||
{devices.map((device, index) => (
|
||||
<div key={device.key} style={{ marginBottom: 16 }}>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="设备编号"
|
||||
name={['devicesForm', index, 'deviceCode']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入设备编号" },
|
||||
{ max: 50, message: "设备编号不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入设备编号"
|
||||
onChange={e => updateDevice(device.key, "deviceCode", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="设备名称"
|
||||
name={['devicesForm', index, 'deviceName']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入设备名称" },
|
||||
{ max: 50, message: "设备名称不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入设备名称"
|
||||
onChange={e => updateDevice(device.key, "deviceName", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="设备分类"
|
||||
name={['devicesForm', index, 'deviceCategory']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入设备分类" },
|
||||
{ max: 50, message: "设备分类不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入设备分类"
|
||||
onChange={e => updateDevice(device.key, "deviceCategory", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="负责单位"
|
||||
name={['devicesForm', index, 'chargeUnit']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入负责单位" },
|
||||
{ max: 50, message: "负责单位不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入负责单位"
|
||||
onChange={e => updateDevice(device.key, "chargeUnit", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="具体位置"
|
||||
name={['devicesForm', index, 'deviceLocation']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入具体位置" },
|
||||
{ max: 50, message: "具体位置不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入具体位置"
|
||||
onChange={e => updateDevice(device.key, "deviceLocation", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="设备参数和规格"
|
||||
required
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item
|
||||
name={['devicesForm', index, 'paramsSpec']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入设备参数和规格" },
|
||||
{ max: 50, message: "设备参数和规格不能超过50个字符" },
|
||||
]}
|
||||
noStyle
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入设备参数和规格"
|
||||
onChange={e => updateDevice(device.key, "paramsSpec", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Button danger onClick={() => removeDevice(device.key)}>
|
||||
删除
|
||||
</Button>
|
||||
</Space.Compact>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
))}
|
||||
</Card>
|
||||
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "center" }}>
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "center", marginTop: 24 }}>
|
||||
<Space size={16}>
|
||||
<Button onClick={() => props.history.goBack()}>
|
||||
取消
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Form, message, Modal, Space } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
|
|
@ -15,7 +15,47 @@ function List(props) {
|
|||
const [form] = Form.useForm();
|
||||
const query = useGetUrlQuery();
|
||||
|
||||
const { tableProps, getData } = useTable(props["pumpRoomList"], { form });
|
||||
const normalizeBackPath = (path) => {
|
||||
if (!path) return "";
|
||||
try {
|
||||
const url = new URL(path, window.location.origin);
|
||||
const appPrefix = `/${window.process?.env?.appIdentifier || "fireResource"}`;
|
||||
let pathname = url.pathname;
|
||||
if (pathname.startsWith(`${appPrefix}/`)) pathname = pathname.slice(appPrefix.length);
|
||||
else if (pathname === appPrefix) pathname = "/";
|
||||
return `${pathname}${url.search}`;
|
||||
} catch (error) {
|
||||
return path;
|
||||
}
|
||||
};
|
||||
|
||||
const isFromSupervision = !!query.eqCorpId;
|
||||
const supervisionBackPath = normalizeBackPath(
|
||||
query.backPath
|
||||
|| props.location?.state?.backPath
|
||||
|| window.sessionStorage.getItem("supervisionFireResourceStatsBackPath")
|
||||
|| "",
|
||||
);
|
||||
const pageHistory = isFromSupervision
|
||||
? {
|
||||
...props.history,
|
||||
goBack: () => {
|
||||
if (supervisionBackPath) {
|
||||
props.history.push(supervisionBackPath);
|
||||
return true;
|
||||
}
|
||||
window.history.back();
|
||||
return true;
|
||||
},
|
||||
}
|
||||
: props.history;
|
||||
|
||||
const { tableProps, getData } = useTable(props["pumpRoomList"], {
|
||||
form,
|
||||
params: () => (query.eqCorpId ? { eqCorpId: query.eqCorpId } : {}),
|
||||
});
|
||||
|
||||
const handleSearch = values => getData(query.eqCorpId ? { ...values, eqCorpId: query.eqCorpId } : values);
|
||||
|
||||
const [deleting, setDeleting] = useState(false);
|
||||
const [statusDict, setStatusDict] = useState([]);
|
||||
|
|
@ -23,19 +63,15 @@ function List(props) {
|
|||
|
||||
const { getDictionary } = useDictionary();
|
||||
|
||||
// 一次性初始化字典和表单
|
||||
useEffect(() => {
|
||||
const init = async () => {
|
||||
// 加载字典
|
||||
try {
|
||||
const dict = await getDictionary({ dictValue: "fire_resource_contro_root_type" });
|
||||
setStatusDict(Array.isArray(dict) ? dict : []);
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
setStatusDict([]);
|
||||
}
|
||||
|
||||
// 设置表单初始值并加载数据
|
||||
if (query.eqCorpId) {
|
||||
form.setFieldsValue({ eqCorpId: query.eqCorpId });
|
||||
}
|
||||
|
|
@ -44,12 +80,9 @@ function List(props) {
|
|||
setInitialized(true);
|
||||
};
|
||||
|
||||
if (!initialized) {
|
||||
init();
|
||||
}
|
||||
if (!initialized) init();
|
||||
}, []);
|
||||
|
||||
// 监听 eqCorpId 变化
|
||||
useEffect(() => {
|
||||
if (initialized && query.eqCorpId) {
|
||||
const currentCorpId = form.getFieldValue("eqCorpId");
|
||||
|
|
@ -84,11 +117,9 @@ function List(props) {
|
|||
await props["pumpRoomDelete"]({ id });
|
||||
message.success("删除成功");
|
||||
getData();
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
message.error("删除失败");
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
setDeleting(false);
|
||||
}
|
||||
},
|
||||
|
|
@ -96,109 +127,41 @@ function List(props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Page isShowAllAction={isFromSupervision} isShowFooter={false} history={pageHistory}>
|
||||
<Search
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
options={[
|
||||
{
|
||||
name: "likePumpRoomName",
|
||||
label: "消防泵房名称",
|
||||
},
|
||||
{
|
||||
name: "eqPumpRoomStatus",
|
||||
label: "消防泵房状态",
|
||||
render: (<DictionarySelect dictValue="fire_resource_contro_root_type" />),
|
||||
},
|
||||
{
|
||||
name: "eqCorpId",
|
||||
onlyForLabel: true,
|
||||
},
|
||||
{ name: "likePumpRoomName", label: "消防泵房名称" },
|
||||
{ name: "eqPumpRoomStatus", label: "消防泵房状态", render: (<DictionarySelect dictValue="fire_resource_contro_root_type" />) },
|
||||
{ name: "eqCorpId", onlyForLabel: true },
|
||||
]}
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
values={query.eqCorpId ? { eqCorpId: query.eqCorpId } : {}}
|
||||
onFinish={handleSearch}
|
||||
/>
|
||||
|
||||
<Table
|
||||
toolBarRender={() => (
|
||||
<Space>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
props.history.push("./add");
|
||||
}}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => props.history.push("./add")}>新增</Button>
|
||||
</Space>
|
||||
)}
|
||||
columns={[
|
||||
{
|
||||
title: "消防泵房名称",
|
||||
dataIndex: "pumpRoomName",
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "消防泵房状态",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: (_, record) => getStatusLabel(record),
|
||||
},
|
||||
{
|
||||
title: "负责人",
|
||||
dataIndex: "principalName",
|
||||
width: 120,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "负责人手机号",
|
||||
dataIndex: "principalPhone",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "设备数",
|
||||
dataIndex: "deviceCount",
|
||||
width: 100,
|
||||
align: "center",
|
||||
render: text => text || 0,
|
||||
},
|
||||
{ title: "消防泵房名称", dataIndex: "pumpRoomName", width: 200, ellipsis: true },
|
||||
{ title: "消防泵房状态", width: 150, align: "center", ellipsis: true, render: (_, record) => getStatusLabel(record) },
|
||||
{ title: "负责人", dataIndex: "principalName", width: 120, align: "center", ellipsis: true },
|
||||
{ title: "负责人手机号", dataIndex: "principalPhone", width: 150, align: "center", ellipsis: true },
|
||||
{ title: "设备数", dataIndex: "deviceCount", width: 100, align: "center", render: text => text || 0 },
|
||||
{
|
||||
title: "操作",
|
||||
width: 200,
|
||||
align: "center",
|
||||
render: (_, record) => (
|
||||
<Space size={8}>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
props.history.push(`./view?id=${record.id}`);
|
||||
}}
|
||||
>
|
||||
查看
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
props.history.push(`./add?id=${record.id}`);
|
||||
}}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
onClick={() => onDelete(record.id)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
<Button type="link" size="small" onClick={() => props.history.push(`./view?id=${record.id}`)}>查看</Button>
|
||||
<Button type="link" size="small" onClick={() => props.history.push(`./add?id=${record.id}`)}>编辑</Button>
|
||||
<Button type="link" size="small" danger onClick={() => onDelete(record.id)}>删除</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ function View(props) {
|
|||
{
|
||||
title: "设备编号",
|
||||
dataIndex: "deviceCode",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -111,7 +110,6 @@ function View(props) {
|
|||
{
|
||||
title: "设备名称",
|
||||
dataIndex: "deviceName",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -119,7 +117,6 @@ function View(props) {
|
|||
{
|
||||
title: "设备分类",
|
||||
dataIndex: "deviceCategory",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -127,7 +124,6 @@ function View(props) {
|
|||
{
|
||||
title: "负责单位",
|
||||
dataIndex: "chargeUnit",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -135,7 +131,6 @@ function View(props) {
|
|||
{
|
||||
title: "具体位置",
|
||||
dataIndex: "deviceLocation",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
|
|
@ -151,13 +146,13 @@ function View(props) {
|
|||
|
||||
return (
|
||||
<Page
|
||||
headerTitle="查看消防泵房"
|
||||
loading={loading || getFileLoading}
|
||||
isShowFooter={false}
|
||||
isShowBack={false}
|
||||
>
|
||||
{detail && (
|
||||
<div style={{ maxWidth: 1200, margin: "24px auto" }}>
|
||||
<Card title="基本信息" style={{ marginBottom: 24 }}>
|
||||
<div>
|
||||
<Card title="基本信息" bordered={false} style={{ boxShadow: 'none' }}>
|
||||
<Descriptions
|
||||
bordered
|
||||
column={2}
|
||||
|
|
@ -206,18 +201,18 @@ function View(props) {
|
|||
/>
|
||||
</Card>
|
||||
|
||||
<Card title="设备信息" style={{ marginBottom: 24 }}>
|
||||
<Card title="设备信息" style={{ marginTop: 24, boxShadow: 'none' }} bordered={false}>
|
||||
<Table
|
||||
bordered
|
||||
columns={deviceColumns}
|
||||
dataSource={detail.devices || []}
|
||||
pagination={false}
|
||||
rowKey={(record, index) => record.id || `device-${index}`}
|
||||
scroll={{ x: 1000 }}
|
||||
locale={{ emptyText: "暂无设备信息" }}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<div style={{ textAlign: "center", marginTop: 24 }}>
|
||||
<Button onClick={() => props.history.goBack()}>
|
||||
返回
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Card, Col, DatePicker, Form, Input, message, Row, Space, Table } from "antd";
|
||||
import { Button, Card, Col, DatePicker, Form, Input, message, Row, Space } from "antd";
|
||||
import dayjs from "dayjs";
|
||||
import { useEffect, useState } from "react";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
|
|
@ -8,6 +8,22 @@ import DictionarySelect from "zy-react-library/components/Select/Dictionary";
|
|||
import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery";
|
||||
import { NS_RESCUE_TEAM } from "~/enumerate/namespace";
|
||||
|
||||
// 手机号验证正则
|
||||
const MOBILE_PATTERN = /^1[3-9]\d{9}$/;
|
||||
// 固话验证正则(支持区号-号码格式,如:023-12345678 或 直接号码)
|
||||
const LANDLINE_PATTERN = /^(\d{3,4}-?)?\d{7,8}$/;
|
||||
|
||||
// 手机号或固话验证函数
|
||||
const validatePhone = (rule, value) => {
|
||||
if (!value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (MOBILE_PATTERN.test(value) || LANDLINE_PATTERN.test(value)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error("请输入正确的手机号或固话"));
|
||||
};
|
||||
|
||||
function Add(props) {
|
||||
const query = useGetUrlQuery();
|
||||
const [form] = Form.useForm();
|
||||
|
|
@ -15,7 +31,14 @@ function Add(props) {
|
|||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
// 消防队员列表
|
||||
const [rescueMembers, setRescueMembers] = useState([]);
|
||||
const createEmptyMember = () => ({
|
||||
key: `${Date.now()}-${Math.random()}`,
|
||||
personName: "",
|
||||
personPhone: "",
|
||||
dutyDesc: "",
|
||||
roleCode: 1,
|
||||
});
|
||||
const [rescueMembers, setRescueMembers] = useState([createEmptyMember()]);
|
||||
|
||||
// 添加状态保存字典显示名称
|
||||
const [teamTypeName, setTeamTypeName] = useState("");
|
||||
|
|
@ -43,7 +66,16 @@ function Add(props) {
|
|||
|
||||
// 设置消防队员列表
|
||||
if (data.rescueMembers && data.rescueMembers.length > 0) {
|
||||
setRescueMembers(data.rescueMembers.map((item, index) => ({ ...item, key: item.id || index })));
|
||||
const members = data.rescueMembers.map((item, index) => ({ ...item, key: item.id || index }));
|
||||
setRescueMembers(members);
|
||||
// 同步设置Form的队员数据
|
||||
form.setFieldValue('rescueMembersForm', members.map(m => ({
|
||||
personName: m.personName,
|
||||
personPhone: m.personPhone,
|
||||
})));
|
||||
}
|
||||
else {
|
||||
setRescueMembers([createEmptyMember()]);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
|
|
@ -65,15 +97,6 @@ function Add(props) {
|
|||
return;
|
||||
}
|
||||
|
||||
// 验证消防队员必填项
|
||||
const invalidMember = rescueMembers.find(
|
||||
item => !item.personName || !item.personPhone,
|
||||
);
|
||||
if (invalidMember) {
|
||||
message.warning("请完善消防队员信息");
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
try {
|
||||
const apiMethod = query.id ? props["rescueTeamUpdate"] : props["rescueTeamAdd"];
|
||||
|
|
@ -119,18 +142,21 @@ function Add(props) {
|
|||
|
||||
// 消防队员相关操作
|
||||
const addMember = () => {
|
||||
const newMember = {
|
||||
key: Date.now(),
|
||||
personName: "",
|
||||
personPhone: "",
|
||||
dutyDesc: "",
|
||||
roleCode: 1,
|
||||
};
|
||||
setRescueMembers([...rescueMembers, newMember]);
|
||||
const newMembers = [...rescueMembers, createEmptyMember()];
|
||||
setRescueMembers(newMembers);
|
||||
// 同步更新Form
|
||||
const formMembers = form.getFieldValue('rescueMembersForm') || [];
|
||||
form.setFieldValue('rescueMembersForm', [...formMembers, { personName: '', personPhone: '' }]);
|
||||
};
|
||||
|
||||
const removeMember = (key) => {
|
||||
setRescueMembers(rescueMembers.filter(item => item.key !== key));
|
||||
const index = rescueMembers.findIndex(item => item.key === key);
|
||||
const newMembers = rescueMembers.filter(item => item.key !== key);
|
||||
setRescueMembers(newMembers);
|
||||
// 同步更新Form
|
||||
const formMembers = form.getFieldValue('rescueMembersForm') || [];
|
||||
formMembers.splice(index, 1);
|
||||
form.setFieldValue('rescueMembersForm', [...formMembers]);
|
||||
};
|
||||
|
||||
const updateMember = (key, field, value) => {
|
||||
|
|
@ -139,63 +165,20 @@ function Add(props) {
|
|||
);
|
||||
};
|
||||
|
||||
// 消防队员表格列定义
|
||||
const memberColumns = [
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
队员姓名
|
||||
</>),
|
||||
dataIndex: "personName",
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入队员姓名"
|
||||
onChange={e => updateMember(record.key, "personName", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (<>
|
||||
<span style={{ color: "red" }}>*</span>
|
||||
队员电话
|
||||
</>),
|
||||
dataIndex: "personPhone",
|
||||
render: (text, record) => (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="请输入队员电话"
|
||||
maxLength={11}
|
||||
onChange={e => updateMember(record.key, "personPhone", e.target.value)}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 80,
|
||||
align: "center",
|
||||
render: (_, record) => (
|
||||
<Button type="link" danger onClick={() => removeMember(record.key)}>
|
||||
删除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Page
|
||||
headerTitle={query.id ? "编辑救援队" : "新增救援队"}
|
||||
loading={loading}
|
||||
isShowFooter={false}
|
||||
isShowBack={false}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
onFinish={onFinish}
|
||||
style={{ maxWidth: 1200, margin: "24px auto" }}
|
||||
>
|
||||
<Card title="基本信息" style={{ marginBottom: 24 }}>
|
||||
<Card title="基本信息" bordered={false}>
|
||||
<Form.Item name="teamId" hidden>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
|
|
@ -210,7 +193,7 @@ function Add(props) {
|
|||
wrapperCol={{ span: 21 }}
|
||||
rules={[
|
||||
{ required: true, message: "请输入救援队名称" },
|
||||
{ max: 100, message: "救援队名称不能超过100个字符" },
|
||||
{ max: 50, message: "救援队名称不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入救援队名称" />
|
||||
|
|
@ -242,7 +225,7 @@ function Add(props) {
|
|||
name="chargeOrgDept"
|
||||
rules={[
|
||||
{ required: true, message: "请输入负责人单位或部门" },
|
||||
{ max: 200, message: "负责人单位或部门不能超过200个字符" },
|
||||
{ max: 50, message: "负责人单位或部门不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入负责人单位或部门" />
|
||||
|
|
@ -270,11 +253,18 @@ function Add(props) {
|
|||
label="队长电话"
|
||||
name="captainPhone"
|
||||
rules={[
|
||||
{ required: true, message: "请输入队长电话" },
|
||||
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号" },
|
||||
{ validator: validatePhone },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入队长电话" maxLength={11} />
|
||||
<Input
|
||||
placeholder="请输入队长电话"
|
||||
maxLength={20}
|
||||
onChange={e => {
|
||||
// 只允许输入数字和连字符
|
||||
const value = e.target.value.replace(/[^\d-]/g, '');
|
||||
form.setFieldValue('captainPhone', value);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
@ -298,7 +288,6 @@ function Add(props) {
|
|||
<Form.Item
|
||||
label="建立日期"
|
||||
name="establishDate"
|
||||
rules={[{ required: true, message: "请选择建立日期" }]}
|
||||
>
|
||||
<DatePicker
|
||||
placeholder="请选择日期"
|
||||
|
|
@ -332,8 +321,7 @@ function Add(props) {
|
|||
label="职责和任务范围"
|
||||
name="dutyScope"
|
||||
rules={[
|
||||
{ required: true, message: "请输入职责和任务范围" },
|
||||
{ max: 500, message: "职责和任务范围不能超过500个字符" },
|
||||
{ max: 50, message: "职责和任务范围不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入职责和任务范围" />
|
||||
|
|
@ -349,18 +337,66 @@ function Add(props) {
|
|||
新增
|
||||
</Button>
|
||||
)}
|
||||
style={{ marginBottom: 24 }}
|
||||
style={{ marginTop: 24 }}
|
||||
bordered={false}
|
||||
>
|
||||
<Table
|
||||
columns={memberColumns}
|
||||
dataSource={rescueMembers}
|
||||
pagination={false}
|
||||
rowKey="key"
|
||||
locale={{ emptyText: "暂无队员信息,请点击新增按钮添加" }}
|
||||
/>
|
||||
{rescueMembers.map((member, index) => (
|
||||
<Row gutter={24} key={member.key} style={{ marginBottom: 16 }}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label={`队员${index + 1}`}
|
||||
name={['rescueMembersForm', index, 'personName']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入队员姓名" },
|
||||
{ max: 50, message: "队员姓名不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入队员姓名"
|
||||
onChange={e => updateMember(member.key, "personName", e.target.value)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label={`队员${index + 1}电话`}
|
||||
required
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item
|
||||
name={['rescueMembersForm', index, 'personPhone']}
|
||||
rules={[
|
||||
{ required: true, message: "请输入队员电话" },
|
||||
{ validator: validatePhone },
|
||||
]}
|
||||
noStyle
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入队员电话"
|
||||
maxLength={20}
|
||||
onChange={e => {
|
||||
const value = e.target.value.replace(/[^\d-]/g, '');
|
||||
updateMember(member.key, "personPhone", value);
|
||||
form.setFieldValue(['rescueMembersForm', index, 'personPhone'], value);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
{index !== 0 && (
|
||||
<Button
|
||||
danger
|
||||
onClick={() => removeMember(member.key)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
)}
|
||||
</Space.Compact>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
))}
|
||||
</Card>
|
||||
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "center" }}>
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "center", marginTop: 24 }}>
|
||||
<Space size={16}>
|
||||
<Button onClick={() => props.history.goBack()}>
|
||||
取消
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Form, message, Modal, Space } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
|
|
@ -14,12 +14,51 @@ function List(props) {
|
|||
const [form] = Form.useForm();
|
||||
const query = useGetUrlQuery();
|
||||
|
||||
const { tableProps, getData } = useTable(props["rescueTeamList"], { form });
|
||||
const normalizeBackPath = (path) => {
|
||||
if (!path) return "";
|
||||
try {
|
||||
const url = new URL(path, window.location.origin);
|
||||
const appPrefix = `/${window.process?.env?.appIdentifier || "fireResource"}`;
|
||||
let pathname = url.pathname;
|
||||
if (pathname.startsWith(`${appPrefix}/`)) pathname = pathname.slice(appPrefix.length);
|
||||
else if (pathname === appPrefix) pathname = "/";
|
||||
return `${pathname}${url.search}`;
|
||||
} catch (error) {
|
||||
return path;
|
||||
}
|
||||
};
|
||||
|
||||
const isFromSupervision = !!query.eqCorpId;
|
||||
const supervisionBackPath = normalizeBackPath(
|
||||
query.backPath
|
||||
|| props.location?.state?.backPath
|
||||
|| window.sessionStorage.getItem("supervisionFireResourceStatsBackPath")
|
||||
|| "",
|
||||
);
|
||||
const pageHistory = isFromSupervision
|
||||
? {
|
||||
...props.history,
|
||||
goBack: () => {
|
||||
if (supervisionBackPath) {
|
||||
props.history.push(supervisionBackPath);
|
||||
return true;
|
||||
}
|
||||
window.history.back();
|
||||
return true;
|
||||
},
|
||||
}
|
||||
: props.history;
|
||||
|
||||
const { tableProps, getData } = useTable(props["rescueTeamList"], {
|
||||
form,
|
||||
params: () => (query.eqCorpId ? { eqCorpId: query.eqCorpId } : {}),
|
||||
});
|
||||
|
||||
const handleSearch = values => getData(query.eqCorpId ? { ...values, eqCorpId: query.eqCorpId } : values);
|
||||
|
||||
const [deleting, setDeleting] = useState(false);
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
|
||||
// 一次性初始化表单
|
||||
useEffect(() => {
|
||||
if (!initialized) {
|
||||
if (query.eqCorpId) {
|
||||
|
|
@ -30,7 +69,6 @@ function List(props) {
|
|||
}
|
||||
}, []);
|
||||
|
||||
// 监听 eqCorpId 变化
|
||||
useEffect(() => {
|
||||
if (initialized && query.eqCorpId) {
|
||||
const currentCorpId = form.getFieldValue("eqCorpId");
|
||||
|
|
@ -58,11 +96,9 @@ function List(props) {
|
|||
await props["rescueTeamDelete"]({ id });
|
||||
message.success("删除成功");
|
||||
getData();
|
||||
}
|
||||
catch (error) {
|
||||
} catch (error) {
|
||||
message.error("删除失败");
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
setDeleting(false);
|
||||
}
|
||||
},
|
||||
|
|
@ -70,136 +106,46 @@ function List(props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Page isShowAllAction={isFromSupervision} isShowFooter={false} history={pageHistory}>
|
||||
<Search
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
options={[
|
||||
{
|
||||
name: "likeTeamName",
|
||||
label: "救援队名称",
|
||||
},
|
||||
{
|
||||
name: "eqTeamType",
|
||||
label: "类型",
|
||||
render: (<DictionarySelect dictValue="fire_resource_team_type" />),
|
||||
},
|
||||
{
|
||||
name: "likeChargeOrgDept",
|
||||
label: "负责人单位或部门",
|
||||
},
|
||||
{
|
||||
name: "likeCaptainName",
|
||||
label: "队长",
|
||||
},
|
||||
{
|
||||
name: "eqRegionScope",
|
||||
label: "所属区域或范围",
|
||||
render: (<DictionarySelect dictValue="fire_resource_area_scope" />),
|
||||
},
|
||||
{
|
||||
name: "eqCorpId",
|
||||
onlyForLabel: true,
|
||||
},
|
||||
{ name: "likeTeamName", label: "救援队名称" },
|
||||
{ name: "eqTeamType", label: "类型", render: (<DictionarySelect dictValue="fire_resource_team_type" />) },
|
||||
{ name: "likeChargeOrgDept", label: "负责人单位或部门" },
|
||||
{ name: "likeCaptainName", label: "队长" },
|
||||
{ name: "eqRegionScope", label: "所属区域或范围", render: (<DictionarySelect dictValue="fire_resource_area_scope" />) },
|
||||
{ name: "eqCorpId", onlyForLabel: true },
|
||||
]}
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
values={query.eqCorpId ? { eqCorpId: query.eqCorpId } : {}}
|
||||
onFinish={handleSearch}
|
||||
/>
|
||||
|
||||
<Table
|
||||
toolBarRender={() => (
|
||||
<Space>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
props.history.push("./add");
|
||||
}}
|
||||
>
|
||||
新增
|
||||
</Button>
|
||||
<Button type="primary" onClick={() => props.history.push("./add")}>新增</Button>
|
||||
</Space>
|
||||
)}
|
||||
columns={[
|
||||
{
|
||||
title: "救援队名称",
|
||||
dataIndex: "teamName",
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "类型",
|
||||
dataIndex: "teamTypeName",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "负责人单位或部门",
|
||||
dataIndex: "chargeOrgDept",
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "队长",
|
||||
dataIndex: "captainName",
|
||||
width: 120,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "指挥人员",
|
||||
dataIndex: "commandCrew",
|
||||
width: 120,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "所属区域或范围",
|
||||
dataIndex: "regionScopeName",
|
||||
width: 150,
|
||||
align: "center",
|
||||
ellipsis: true,
|
||||
render: text => text || "-",
|
||||
},
|
||||
{
|
||||
title: "队员人数",
|
||||
dataIndex: "memberCount",
|
||||
width: 100,
|
||||
align: "center",
|
||||
render: text => text || 0,
|
||||
},
|
||||
{ title: "救援队名称", dataIndex: "teamName", width: 200, ellipsis: true },
|
||||
{ title: "类型", dataIndex: "teamTypeName", width: 150, align: "center", ellipsis: true },
|
||||
{ title: "负责人单位或部门", dataIndex: "chargeOrgDept", width: 200, ellipsis: true },
|
||||
{ title: "队长", dataIndex: "captainName", width: 120, align: "center", ellipsis: true },
|
||||
{ title: "指挥人员", dataIndex: "commandCrew", width: 120, align: "center", ellipsis: true },
|
||||
{ title: "所属区域或范围", dataIndex: "regionScopeName", width: 150, align: "center", ellipsis: true, render: text => text || "-" },
|
||||
{ title: "队员人数", dataIndex: "memberCount", width: 100, align: "center", render: text => text || 0 },
|
||||
{
|
||||
title: "操作",
|
||||
width: 200,
|
||||
align: "center",
|
||||
render: (_, record) => (
|
||||
<Space size={8}>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
props.history.push(`./view?id=${record.id}`);
|
||||
}}
|
||||
>
|
||||
查看
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
props.history.push(`./add?id=${record.id}`);
|
||||
}}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
danger
|
||||
onClick={() => onDelete(record.id)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
<Button type="link" size="small" onClick={() => props.history.push(`./view?id=${record.id}`)}>查看</Button>
|
||||
<Button type="link" size="small" onClick={() => props.history.push(`./add?id=${record.id}`)}>编辑</Button>
|
||||
<Button type="link" size="small" danger onClick={() => onDelete(record.id)}>删除</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -33,31 +33,35 @@ function View(props) {
|
|||
const memberColumns = [
|
||||
{
|
||||
title: "序号",
|
||||
width: 80,
|
||||
width: 10,
|
||||
align: "center",
|
||||
render: (_, __, index) => index + 1,
|
||||
},
|
||||
{
|
||||
title: "队员姓名",
|
||||
title: "队员",
|
||||
dataIndex: "personName",
|
||||
align: "center",
|
||||
width: 140,
|
||||
render: text => text || "-",
|
||||
},
|
||||
{
|
||||
title: "队员电话",
|
||||
dataIndex: "personPhone",
|
||||
align: "center",
|
||||
width: 140,
|
||||
render: text => text || "-",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Page
|
||||
headerTitle="查看救援队"
|
||||
loading={loading}
|
||||
isShowFooter={false}
|
||||
isShowBack={false}
|
||||
>
|
||||
{detail && (
|
||||
<div style={{ maxWidth: 1200, margin: "24px auto" }}>
|
||||
<Card title="基本信息" style={{ marginBottom: 24 }}>
|
||||
<div>
|
||||
<Card title="基本信息" bordered={false}>
|
||||
<Descriptions
|
||||
bordered
|
||||
column={2}
|
||||
|
|
@ -109,8 +113,9 @@ function View(props) {
|
|||
/>
|
||||
</Card>
|
||||
|
||||
<Card title="队员信息" style={{ marginBottom: 24 }}>
|
||||
<Card title="队员信息" style={{ marginTop: 24 }} bordered={false}>
|
||||
<Table
|
||||
bordered
|
||||
columns={memberColumns}
|
||||
dataSource={detail.rescueMembers || []}
|
||||
pagination={false}
|
||||
|
|
@ -119,7 +124,7 @@ function View(props) {
|
|||
/>
|
||||
</Card>
|
||||
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<div style={{ textAlign: "center", marginTop: 24 }}>
|
||||
<Button onClick={() => props.history.goBack()}>
|
||||
返回
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Button, Card, Col, Form, Input, InputNumber, message, Row, Space } from "antd";
|
||||
import { Button, Card, Col, Form, Input, message, Row, Space } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import MapSelector from "zy-react-library/components/Map/MapSelector";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
|
|
@ -66,18 +66,17 @@ function Add(props) {
|
|||
|
||||
return (
|
||||
<Page
|
||||
headerTitle={query.id ? "编辑消防水源" : "新增消防水源"}
|
||||
loading={loading}
|
||||
isShowFooter={false}
|
||||
isShowBack={false}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
labelCol={{ span: 6 }}
|
||||
wrapperCol={{ span: 18 }}
|
||||
onFinish={onFinish}
|
||||
style={{ maxWidth: 1200, margin: "24px auto" }}
|
||||
>
|
||||
<Card title="基本信息" style={{ marginBottom: 24 }}>
|
||||
<Card title="基本信息" bordered={false} style={{ boxShadow: 'none' }}>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
|
|
@ -85,7 +84,7 @@ function Add(props) {
|
|||
name="waterSourceName"
|
||||
rules={[
|
||||
{ required: true, message: "请输入消防水源名称" },
|
||||
{ max: 100, message: "消防水源名称不能超过100个字符" },
|
||||
{ max: 50, message: "消防水源名称不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入消防水源名称" />
|
||||
|
|
@ -120,7 +119,7 @@ function Add(props) {
|
|||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="纬度"
|
||||
required
|
||||
rules={[{ required: true, message: "请选择纬度" }]}
|
||||
>
|
||||
<Space.Compact style={{ width: "100%" }}>
|
||||
<Form.Item
|
||||
|
|
@ -145,7 +144,7 @@ function Add(props) {
|
|||
name="belongOrgDept"
|
||||
rules={[
|
||||
{ required: true, message: "请输入所属单位或部门" },
|
||||
{ max: 200, message: "所属单位或部门不能超过200个字符" },
|
||||
{ max: 50, message: "所属单位或部门不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入所属单位或部门" />
|
||||
|
|
@ -158,7 +157,7 @@ function Add(props) {
|
|||
name="waterLocation"
|
||||
rules={[
|
||||
{ required: true, message: "请输入水源位置" },
|
||||
{ max: 200, message: "水源位置不能超过200个字符" },
|
||||
{ max: 50, message: "水源位置不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入水源位置" />
|
||||
|
|
@ -171,7 +170,10 @@ function Add(props) {
|
|||
<Form.Item
|
||||
label="接口形式"
|
||||
name="interfaceForm"
|
||||
rules={[{ required: true, message: "请输入接口形式" }]}
|
||||
rules={[
|
||||
{ required: true, message: "请输入接口形式" },
|
||||
{ max: 50, message: "接口形式不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入接口形式" />
|
||||
</Form.Item>
|
||||
|
|
@ -181,7 +183,10 @@ function Add(props) {
|
|||
<Form.Item
|
||||
label="水源类型"
|
||||
name="waterType"
|
||||
rules={[{ required: true, message: "请输入水源类型" }]}
|
||||
rules={[
|
||||
{ required: true, message: "请输入水源类型" },
|
||||
{ max: 50, message: "水源类型不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入水源类型" />
|
||||
</Form.Item>
|
||||
|
|
@ -193,7 +198,10 @@ function Add(props) {
|
|||
<Form.Item
|
||||
label="水源编号"
|
||||
name="waterCode"
|
||||
rules={[{ required: true, message: "请输入水源编号" }]}
|
||||
rules={[
|
||||
{ required: true, message: "请输入水源编号" },
|
||||
{ max: 50, message: "水源编号不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入水源编号" />
|
||||
</Form.Item>
|
||||
|
|
@ -205,11 +213,7 @@ function Add(props) {
|
|||
name="suctionSpec"
|
||||
rules={[{ required: true, message: "请输入吸水口规格" }]}
|
||||
>
|
||||
<InputNumber
|
||||
placeholder="请输入吸水口规格"
|
||||
style={{ width: "100%" }}
|
||||
min={0}
|
||||
/>
|
||||
<Input placeholder="请输入吸水口规格" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
@ -219,7 +223,10 @@ function Add(props) {
|
|||
<Form.Item
|
||||
label="水源容量"
|
||||
name="capacity"
|
||||
rules={[{ required: true, message: "请输入水源容量" }]}
|
||||
rules={[
|
||||
{ required: true, message: "请输入水源容量" },
|
||||
{ max: 50, message: "水源容量不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入水源容量" />
|
||||
</Form.Item>
|
||||
|
|
@ -229,7 +236,10 @@ function Add(props) {
|
|||
<Form.Item
|
||||
label="供水能力"
|
||||
name="supplyAbility"
|
||||
rules={[{ required: true, message: "请输入供水能力" }]}
|
||||
rules={[
|
||||
{ required: true, message: "请输入供水能力" },
|
||||
{ max: 50, message: "供水能力不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入供水能力" />
|
||||
</Form.Item>
|
||||
|
|
@ -241,7 +251,10 @@ function Add(props) {
|
|||
<Form.Item
|
||||
label="设备清单"
|
||||
name="equipmentList"
|
||||
rules={[{ required: true, message: "请输入设备清单" }]}
|
||||
rules={[
|
||||
{ required: true, message: "请输入设备清单" },
|
||||
{ max: 50, message: "设备清单不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入设备清单" />
|
||||
</Form.Item>
|
||||
|
|
@ -249,7 +262,7 @@ function Add(props) {
|
|||
</Row>
|
||||
</Card>
|
||||
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "center" }}>
|
||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "center", marginTop: 24 }}>
|
||||
<Space size={16}>
|
||||
<Button onClick={() => props.history.goBack()}>
|
||||
取消
|
||||
|
|
|
|||
|
|
@ -14,12 +14,48 @@ import { NS_WATER_SOURCE } from "~/enumerate/namespace";
|
|||
function List(props) {
|
||||
const [form] = Form.useForm();
|
||||
const query = useGetUrlQuery();
|
||||
const normalizeBackPath = (path) => {
|
||||
if (!path)
|
||||
return "";
|
||||
try {
|
||||
const url = new URL(path, window.location.origin);
|
||||
const appPrefix = `/${window.process?.env?.appIdentifier || "fireResource"}`;
|
||||
let pathname = url.pathname;
|
||||
if (pathname.startsWith(`${appPrefix}/`))
|
||||
pathname = pathname.slice(appPrefix.length);
|
||||
else if (pathname === appPrefix)
|
||||
pathname = "/";
|
||||
return `${pathname}${url.search}`;
|
||||
}
|
||||
catch (error) {
|
||||
return path;
|
||||
}
|
||||
};
|
||||
const isFromSupervision = !!query.eqCorpId;
|
||||
const supervisionBackPath = normalizeBackPath(query.backPath
|
||||
|| props.location?.state?.backPath
|
||||
|| window.sessionStorage.getItem("supervisionFireResourceStatsBackPath")
|
||||
|| "");
|
||||
const pageHistory = isFromSupervision
|
||||
? {
|
||||
...props.history,
|
||||
goBack: () => {
|
||||
if (supervisionBackPath) {
|
||||
props.history.push(supervisionBackPath);
|
||||
return true;
|
||||
}
|
||||
window.history.back();
|
||||
return true;
|
||||
},
|
||||
}
|
||||
: props.history;
|
||||
|
||||
const { tableProps, getData } = useTable(props["waterSourceList"], {
|
||||
form,
|
||||
params: () => (query.eqCorpId ? { eqCorpId: query.eqCorpId } : {}),
|
||||
useStorageQueryCriteria: false,
|
||||
});
|
||||
const handleSearch = values => getData(query.eqCorpId ? { ...values, eqCorpId: query.eqCorpId } : values);
|
||||
|
||||
const [deleting, setDeleting] = useState(false);
|
||||
const corpIdRef = useRef(query.eqCorpId);
|
||||
|
|
@ -107,13 +143,18 @@ function List(props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Page
|
||||
isShowAllAction={isFromSupervision}
|
||||
isShowFooter={false}
|
||||
history={pageHistory}
|
||||
>
|
||||
<Search
|
||||
labelCol={{ span: 8 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
options={searchOptions}
|
||||
form={form}
|
||||
onFinish={getData}
|
||||
values={query.eqCorpId ? { eqCorpId: query.eqCorpId } : {}}
|
||||
onFinish={handleSearch}
|
||||
/>
|
||||
|
||||
<Table
|
||||
|
|
|
|||
|
|
@ -55,13 +55,13 @@ function View(props) {
|
|||
|
||||
return (
|
||||
<Page
|
||||
headerTitle="查看消防水源"
|
||||
loading={loading}
|
||||
isShowFooter={false}
|
||||
isShowBack={false}
|
||||
>
|
||||
{detail && (
|
||||
<div style={{ maxWidth: 1200, margin: "24px auto" }}>
|
||||
<Card title="基本信息" style={{ marginBottom: 24 }}>
|
||||
<div>
|
||||
<Card title="基本信息" bordered={false} style={{ boxShadow: 'none' }}>
|
||||
<Descriptions
|
||||
bordered
|
||||
column={2}
|
||||
|
|
@ -128,7 +128,7 @@ function View(props) {
|
|||
/>
|
||||
</Card>
|
||||
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<div style={{ textAlign: "center", marginTop: 24 }}>
|
||||
<Button onClick={() => props.history.goBack()}>
|
||||
返回
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Permission } from "@cqsjjb/jjb-common-decorator/permission";
|
||||
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
||||
import { Form } from "antd";
|
||||
import Page from "zy-react-library/components/Page";
|
||||
|
|
@ -13,20 +13,58 @@ function FireResourceStats(props) {
|
|||
const { tableProps, getData } = useTable(props["fireResourceStatsList"], { form });
|
||||
|
||||
const handleViewDetail = (record, type) => {
|
||||
// 跳转到对应的详情列表页面
|
||||
const routeMap = {
|
||||
rescueTeam: "/container/branchCompany/rescueTeam/list",
|
||||
controlRoom: "/container/branchCompany/controlRoom/list",
|
||||
pumpRoom: "/container/branchCompany/pumpRoom/list",
|
||||
waterSource: "/container/branchCompany/waterSource/list",
|
||||
};
|
||||
|
||||
|
||||
if (routeMap[type]) {
|
||||
const corpId = record.corpId || record.companyId || "";
|
||||
props.history.push(`${routeMap[type]}?corpId=${corpId}`);
|
||||
const backPath = `${props.location?.pathname || window.location.pathname}${props.location?.search || window.location.search || ""}`;
|
||||
window.sessionStorage.setItem("supervisionFireResourceStatsBackPath", backPath);
|
||||
props.history.push({
|
||||
pathname: routeMap[type],
|
||||
search: `?eqCorpId=${corpId}&backPath=${encodeURIComponent(backPath)}`,
|
||||
state: { backPath },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const renderCountLink = (text, record, type) => {
|
||||
const fieldMap = {
|
||||
rescueTeam: "rescueTeamCount",
|
||||
controlRoom: "controlRoomCount",
|
||||
pumpRoom: "pumpRoomCount",
|
||||
waterSource: "waterSourceCount",
|
||||
};
|
||||
const rawCount = text ?? record?.[fieldMap[type]] ?? 0;
|
||||
const count = rawCount === "" ? 0 : rawCount;
|
||||
const isZero = count === 0 || count === "0";
|
||||
|
||||
if (isZero) {
|
||||
return <span style={{ color: "#1677ff", WebkitTextFillColor: "#1677ff" }}>0</span>;
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
style={{ color: "#1677ff", fontWeight: 600, WebkitTextFillColor: "#1677ff" }}
|
||||
onClick={() => handleViewDetail(record, type)}
|
||||
onKeyDown={e => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
handleViewDetail(record, type);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{count}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Page isShowAllAction={false}>
|
||||
<Search
|
||||
|
|
@ -40,67 +78,39 @@ function FireResourceStats(props) {
|
|||
<Table
|
||||
columns={[
|
||||
{ title: "序号", width: 80, align: "center", render: (_, __, index) => index + 1 },
|
||||
{
|
||||
title: "企业名称",
|
||||
{
|
||||
title: "企业名称",
|
||||
dataIndex: "companyName",
|
||||
ellipsis: true,
|
||||
render: (text) => text || "一公司",
|
||||
render: text => text || "一公司",
|
||||
},
|
||||
{
|
||||
title: "消防救援队数",
|
||||
{
|
||||
title: "消防救援队数",
|
||||
dataIndex: "rescueTeamCount",
|
||||
width: 140,
|
||||
align: "center",
|
||||
render: (text, record) => (
|
||||
<a
|
||||
style={{ color: "#1677ff", fontWeight: 600, textDecoration: "underline" }}
|
||||
onClick={() => handleViewDetail(record, "rescueTeam")}
|
||||
>
|
||||
{text || 0}
|
||||
</a>
|
||||
),
|
||||
render: (text, record) => renderCountLink(text, record, "rescueTeam"),
|
||||
},
|
||||
{
|
||||
title: "消防控制室数",
|
||||
{
|
||||
title: "消防控制室数",
|
||||
dataIndex: "controlRoomCount",
|
||||
width: 140,
|
||||
align: "center",
|
||||
render: (text, record) => (
|
||||
<a
|
||||
style={{ color: "#1677ff", fontWeight: 600, textDecoration: "underline" }}
|
||||
onClick={() => handleViewDetail(record, "controlRoom")}
|
||||
>
|
||||
{text || 0}
|
||||
</a>
|
||||
),
|
||||
render: (text, record) => renderCountLink(text, record, "controlRoom"),
|
||||
},
|
||||
{
|
||||
title: "消防泵房数",
|
||||
{
|
||||
title: "消防泵房数",
|
||||
dataIndex: "pumpRoomCount",
|
||||
width: 140,
|
||||
align: "center",
|
||||
render: (text, record) => (
|
||||
<a
|
||||
style={{ color: "#1677ff", fontWeight: 600, textDecoration: "underline" }}
|
||||
onClick={() => handleViewDetail(record, "pumpRoom")}
|
||||
>
|
||||
{text || 0}
|
||||
</a>
|
||||
),
|
||||
render: (text, record) => renderCountLink(text, record, "pumpRoom"),
|
||||
},
|
||||
{
|
||||
title: "消防水源数",
|
||||
{
|
||||
title: "消防水源数",
|
||||
dataIndex: "waterSourceCount",
|
||||
width: 140,
|
||||
align: "center",
|
||||
render: (text, record) => (
|
||||
<a
|
||||
style={{ color: "#1677ff", fontWeight: 600, textDecoration: "underline" }}
|
||||
onClick={() => handleViewDetail(record, "waterSource")}
|
||||
>
|
||||
{text || 0}
|
||||
</a>
|
||||
),
|
||||
render: (text, record) => renderCountLink(text, record, "waterSource"),
|
||||
},
|
||||
]}
|
||||
{...tableProps}
|
||||
|
|
@ -110,3 +120,4 @@ function FireResourceStats(props) {
|
|||
}
|
||||
|
||||
export default Connect([NS_FIRE_RESOURCE_STATS], true)(Permission(FireResourceStats));
|
||||
|
||||
|
|
|
|||
|
|
@ -30,22 +30,37 @@ function FireResourceStats(props) {
|
|||
const renderCountLink = (text, record, type) => {
|
||||
const count = text || 0;
|
||||
|
||||
// 如果数量为0,只显示数字不可点击
|
||||
// 数量为0也保持蓝色展示
|
||||
if (count === 0) {
|
||||
return <span style={{ color: "#999" }}>0</span>;
|
||||
return (
|
||||
<span
|
||||
style={{ color: "#1677ff", WebkitTextFillColor: "#1677ff", fontWeight: 600 }}
|
||||
>
|
||||
0
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
style={{
|
||||
color: "#1677ff",
|
||||
WebkitTextFillColor: "#1677ff",
|
||||
fontWeight: 600,
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => handleViewDetail(record, type)}
|
||||
onKeyDown={e => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
handleViewDetail(record, type);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{count}
|
||||
</a>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -109,3 +124,4 @@ function FireResourceStats(props) {
|
|||
}
|
||||
|
||||
export default Connect([NS_FIRE_RESOURCE_STATS], true)(Permission(FireResourceStats));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue