From 8dd9cfddd73768422a5aa9e18ef4a35907a49743 Mon Sep 17 00:00:00 2001 From: shenzhidan Date: Fri, 27 Feb 2026 08:30:45 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.js | 1 + .../BranchCompany/ControlRoom/Add/index.js | 564 ++++++++++-------- .../BranchCompany/ControlRoom/List/index.js | 50 +- .../BranchCompany/ControlRoom/View/index.js | 25 +- .../BranchCompany/FireResourceStats/index.js | 9 +- .../BranchCompany/PumpRoom/Add/index.js | 376 ++++++------ .../BranchCompany/PumpRoom/List/index.js | 159 ++--- .../BranchCompany/PumpRoom/View/index.js | 17 +- .../BranchCompany/RescueTeam/Add/index.js | 204 ++++--- .../BranchCompany/RescueTeam/List/index.js | 182 ++---- .../BranchCompany/RescueTeam/View/index.js | 19 +- .../BranchCompany/WaterSource/Add/index.js | 53 +- .../BranchCompany/WaterSource/List/index.js | 45 +- .../BranchCompany/WaterSource/View/index.js | 8 +- .../Filiale/FireResourceStats/index.js | 105 ++-- .../Supervision/FireResourceStats/index.js | 24 +- 16 files changed, 1000 insertions(+), 841 deletions(-) diff --git a/src/main.js b/src/main.js index 4187033..2ac00e9 100644 --- a/src/main.js +++ b/src/main.js @@ -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); diff --git a/src/pages/Container/BranchCompany/ControlRoom/Add/index.js b/src/pages/Container/BranchCompany/ControlRoom/Add/index.js index 339c8a2..e0e027d 100644 --- a/src/pages/Container/BranchCompany/ControlRoom/Add/index.js +++ b/src/pages/Container/BranchCompany/ControlRoom/Add/index.js @@ -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: (<> - * - 设备名称 - ), - dataIndex: "deviceName", - render: (text, record) => ( - updateDevice(record.key, "deviceName", e.target.value)} - /> - ), - }, - { - title: (<> - * - 设备型号 - ), - dataIndex: "deviceModel", - render: (text, record) => ( - updateDevice(record.key, "deviceModel", e.target.value)} - /> - ), - }, - { - title: (<> - * - 设备数量 - ), - dataIndex: "deviceQty", - render: (text, record) => ( - updateDevice(record.key, "deviceQty", value)} - /> - ), - }, - { - title: (<> - * - 设备位置 - ), - dataIndex: "deviceLocation", - render: (text, record) => ( - updateDevice(record.key, "deviceLocation", e.target.value)} - /> - ), - }, - { - title: "操作", - width: 80, - align: "center", - render: (_, record) => ( - - ), - }, - ]; - - // 人员表格列定义 - const personnelColumns = [ - { - title: (<> - * - 人员姓名 - ), - dataIndex: "personName", - render: (text, record) => ( - updatePersonnel(record.key, "personName", e.target.value)} - /> - ), - }, - { - title: (<> - * - 人员手机号 - ), - dataIndex: "personPhone", - render: (text, record) => ( - updatePersonnel(record.key, "personPhone", e.target.value)} - /> - ), - }, - { - title: "人员值班情况", - dataIndex: "dutyDesc", - render: (text, record) => ( - updatePersonnel(record.key, "dutyDesc", e.target.value)} - /> - ), - }, - { - title: "操作", - width: 80, - align: "center", - render: (_, record) => ( - - ), - }, - ]; - return (
- + {/* 添加隐藏字段保存 roomId */} @@ -437,7 +353,7 @@ function Add(props) { { setDeleteFiles([...deleteFiles, file]); }} @@ -481,41 +397,173 @@ function Add(props) { 新增 )} - style={{ marginBottom: 24 }} > - + {devices.map((device, index) => ( +
+ +
+ + updateDevice(device.key, "deviceName", e.target.value)} + /> + + + + + updateDevice(device.key, "deviceModel", e.target.value)} + /> + + + + + + + updateDevice(device.key, "deviceQty", value)} + /> + + + + + + + updateDevice(device.key, "deviceLocation", e.target.value)} + /> + + + + + + + + ))} + )} - style={{ marginBottom: 24 }} > -
+ {persons.map((person, index) => ( +
+ +
+ + updatePerson(person.key, "personName", e.target.value)} + /> + + + + + { + const value = e.target.value.replace(/\D/g, ''); + updatePerson(person.key, "personPhone", value); + form.setFieldValue(['personsForm', index, 'personPhone'], value); + }} + /> + + + + + + + updatePerson(person.key, "dutyDesc", e.target.value)} + /> + + + +
+ {index > 0 && ( + + )} +
+ + + + ))} - +
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 ( {detail && ( -
- +
+ - +
- +
-
+
diff --git a/src/pages/Container/BranchCompany/FireResourceStats/index.js b/src/pages/Container/BranchCompany/FireResourceStats/index.js index 1fe4816..aaec59d 100644 --- a/src/pages/Container/BranchCompany/FireResourceStats/index.js +++ b/src/pages/Container/BranchCompany/FireResourceStats/index.js @@ -52,7 +52,7 @@ function FireResourceStats(props) { align: "center", render: (text, record) => ( handleViewDetail(record, "rescueTeam")} > {text || 0} @@ -66,7 +66,7 @@ function FireResourceStats(props) { align: "center", render: (text, record) => ( handleViewDetail(record, "controlRoom")} > {text || 0} @@ -80,7 +80,7 @@ function FireResourceStats(props) { align: "center", render: (text, record) => ( handleViewDetail(record, "pumpRoom")} > {text || 0} @@ -94,7 +94,7 @@ function FireResourceStats(props) { align: "center", render: (text, record) => ( handleViewDetail(record, "waterSource")} > {text || 0} @@ -109,3 +109,4 @@ function FireResourceStats(props) { } export default Connect([NS_FIRE_RESOURCE_STATS], true)(Permission(FireResourceStats)); + diff --git a/src/pages/Container/BranchCompany/PumpRoom/Add/index.js b/src/pages/Container/BranchCompany/PumpRoom/Add/index.js index 3e1842e..a72cbf4 100644 --- a/src/pages/Container/BranchCompany/PumpRoom/Add/index.js +++ b/src/pages/Container/BranchCompany/PumpRoom/Add/index.js @@ -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: (<> - * - 设备编号 - ), - dataIndex: "deviceCode", - width: 150, - render: (text, record) => ( - updateDevice(record.key, "deviceCode", e.target.value)} - /> - ), - }, - { - title: (<> - * - 设备名称 - ), - dataIndex: "deviceName", - width: 150, - render: (text, record) => ( - updateDevice(record.key, "deviceName", e.target.value)} - /> - ), - }, - { - title: (<> - * - 设备分类 - ), - dataIndex: "deviceCategory", - width: 150, - render: (text, record) => ( - updateDevice(record.key, "deviceCategory", e.target.value)} - /> - ), - }, - { - title: (<> - * - 负责单位 - ), - dataIndex: "chargeUnit", - width: 150, - render: (text, record) => ( - updateDevice(record.key, "chargeUnit", e.target.value)} - /> - ), - }, - { - title: (<> - * - 具体位置 - ), - dataIndex: "deviceLocation", - width: 150, - render: (text, record) => ( - updateDevice(record.key, "deviceLocation", e.target.value)} - /> - ), - }, - { - title: (<> - * - 设备参数和规格 - ), - dataIndex: "paramsSpec", - width: 180, - render: (text, record) => ( - updateDevice(record.key, "paramsSpec", e.target.value)} - /> - ), - }, - { - title: "操作", - width: 100, - align: "center", - render: (_, record) => ( - - ), - }, - ]; - return ( - + @@ -294,7 +224,7 @@ function Add(props) { name="pumpRoomName" rules={[ { required: true, message: "请输入消防泵房名称" }, - { max: 100, message: "消防泵房名称不能超过100个字符" }, + { max: 50, message: "消防泵房名称不能超过50个字符" }, ]} > @@ -335,10 +265,17 @@ function Add(props) { name="principalPhone" rules={[ { required: true, message: "请输入负责人手机号" }, - { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号" }, + { validator: validatePhone }, ]} > - + { + const value = e.target.value.replace(/\D/g, ''); + form.setFieldValue('principalPhone', value); + }} + /> @@ -357,7 +294,7 @@ function Add(props) {
{ setDeleteFiles([...deleteFiles, file]); }} @@ -406,18 +342,122 @@ function Add(props) { 新增 )} - style={{ marginBottom: 24 }} + style={{ marginTop: 24, boxShadow: 'none' }} + bordered={false} > -
+ {devices.map((device, index) => ( +
+ +
+ + updateDevice(device.key, "deviceCode", e.target.value)} + /> + + + + + updateDevice(device.key, "deviceName", e.target.value)} + /> + + + + + + + updateDevice(device.key, "deviceCategory", e.target.value)} + /> + + + + + updateDevice(device.key, "chargeUnit", e.target.value)} + /> + + + + + + + updateDevice(device.key, "deviceLocation", e.target.value)} + /> + + + + + + + updateDevice(device.key, "paramsSpec", e.target.value)} + /> + + + + + + + + ))} - +
( - + )} 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) => ( - - - + + + ), }, diff --git a/src/pages/Container/BranchCompany/PumpRoom/View/index.js b/src/pages/Container/BranchCompany/PumpRoom/View/index.js index 6fa2694..1760fdd 100644 --- a/src/pages/Container/BranchCompany/PumpRoom/View/index.js +++ b/src/pages/Container/BranchCompany/PumpRoom/View/index.js @@ -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 ( {detail && ( -
- +
+ - +
record.id || `device-${index}`} - scroll={{ x: 1000 }} locale={{ emptyText: "暂无设备信息" }} /> -
+
diff --git a/src/pages/Container/BranchCompany/RescueTeam/Add/index.js b/src/pages/Container/BranchCompany/RescueTeam/Add/index.js index cc737d6..57fc3d7 100644 --- a/src/pages/Container/BranchCompany/RescueTeam/Add/index.js +++ b/src/pages/Container/BranchCompany/RescueTeam/Add/index.js @@ -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: (<> - * - 队员姓名 - ), - dataIndex: "personName", - render: (text, record) => ( - updateMember(record.key, "personName", e.target.value)} - /> - ), - }, - { - title: (<> - * - 队员电话 - ), - dataIndex: "personPhone", - render: (text, record) => ( - updateMember(record.key, "personPhone", e.target.value)} - /> - ), - }, - { - title: "操作", - width: 80, - align: "center", - render: (_, record) => ( - - ), - }, - ]; return ( - + @@ -210,7 +193,7 @@ function Add(props) { wrapperCol={{ span: 21 }} rules={[ { required: true, message: "请输入救援队名称" }, - { max: 100, message: "救援队名称不能超过100个字符" }, + { max: 50, message: "救援队名称不能超过50个字符" }, ]} > @@ -242,7 +225,7 @@ function Add(props) { name="chargeOrgDept" rules={[ { required: true, message: "请输入负责人单位或部门" }, - { max: 200, message: "负责人单位或部门不能超过200个字符" }, + { max: 50, message: "负责人单位或部门不能超过50个字符" }, ]} > @@ -270,11 +253,18 @@ function Add(props) { label="队长电话" name="captainPhone" rules={[ - { required: true, message: "请输入队长电话" }, - { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号" }, + { validator: validatePhone }, ]} > - + { + // 只允许输入数字和连字符 + const value = e.target.value.replace(/[^\d-]/g, ''); + form.setFieldValue('captainPhone', value); + }} + /> @@ -298,7 +288,6 @@ function Add(props) { @@ -349,18 +337,66 @@ function Add(props) { 新增 )} - style={{ marginBottom: 24 }} + style={{ marginTop: 24 }} + bordered={false} > -
+ {rescueMembers.map((member, index) => ( + + + + updateMember(member.key, "personName", e.target.value)} + /> + + + + + + + { + const value = e.target.value.replace(/[^\d-]/g, ''); + updateMember(member.key, "personPhone", value); + form.setFieldValue(['rescueMembersForm', index, 'personPhone'], value); + }} + /> + + {index !== 0 && ( + + )} + + + + + ))} - +
( - + )} 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) => ( - - - + + + ), }, diff --git a/src/pages/Container/BranchCompany/RescueTeam/View/index.js b/src/pages/Container/BranchCompany/RescueTeam/View/index.js index 1383fa2..26803fc 100644 --- a/src/pages/Container/BranchCompany/RescueTeam/View/index.js +++ b/src/pages/Container/BranchCompany/RescueTeam/View/index.js @@ -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 ( {detail && ( -
- +
+ - +
-
+
diff --git a/src/pages/Container/BranchCompany/WaterSource/Add/index.js b/src/pages/Container/BranchCompany/WaterSource/Add/index.js index d2b02a2..00d505c 100644 --- a/src/pages/Container/BranchCompany/WaterSource/Add/index.js +++ b/src/pages/Container/BranchCompany/WaterSource/Add/index.js @@ -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 ( - +
@@ -120,7 +119,7 @@ function Add(props) { @@ -158,7 +157,7 @@ function Add(props) { name="waterLocation" rules={[ { required: true, message: "请输入水源位置" }, - { max: 200, message: "水源位置不能超过200个字符" }, + { max: 50, message: "水源位置不能超过50个字符" }, ]} > @@ -171,7 +170,10 @@ function Add(props) { @@ -181,7 +183,10 @@ function Add(props) { @@ -193,7 +198,10 @@ function Add(props) { @@ -205,11 +213,7 @@ function Add(props) { name="suctionSpec" rules={[{ required: true, message: "请输入吸水口规格" }]} > - + @@ -219,7 +223,10 @@ function Add(props) { @@ -229,7 +236,10 @@ function Add(props) { @@ -241,7 +251,10 @@ function Add(props) { @@ -249,7 +262,7 @@ function Add(props) { - +
{detail && ( -
- +
+ -
+
diff --git a/src/pages/Container/Filiale/FireResourceStats/index.js b/src/pages/Container/Filiale/FireResourceStats/index.js index 80dca6c..c71430b 100644 --- a/src/pages/Container/Filiale/FireResourceStats/index.js +++ b/src/pages/Container/Filiale/FireResourceStats/index.js @@ -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 0; + } + + return ( + handleViewDetail(record, type)} + onKeyDown={e => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + handleViewDetail(record, type); + } + }} + > + {count} + + ); + }; + return ( 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) => ( - handleViewDetail(record, "rescueTeam")} - > - {text || 0} - - ), + render: (text, record) => renderCountLink(text, record, "rescueTeam"), }, - { - title: "消防控制室数", + { + title: "消防控制室数", dataIndex: "controlRoomCount", width: 140, align: "center", - render: (text, record) => ( - handleViewDetail(record, "controlRoom")} - > - {text || 0} - - ), + render: (text, record) => renderCountLink(text, record, "controlRoom"), }, - { - title: "消防泵房数", + { + title: "消防泵房数", dataIndex: "pumpRoomCount", width: 140, align: "center", - render: (text, record) => ( - handleViewDetail(record, "pumpRoom")} - > - {text || 0} - - ), + render: (text, record) => renderCountLink(text, record, "pumpRoom"), }, - { - title: "消防水源数", + { + title: "消防水源数", dataIndex: "waterSourceCount", width: 140, align: "center", - render: (text, record) => ( - handleViewDetail(record, "waterSource")} - > - {text || 0} - - ), + 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)); + diff --git a/src/pages/Container/Supervision/FireResourceStats/index.js b/src/pages/Container/Supervision/FireResourceStats/index.js index 158721b..2270fdd 100644 --- a/src/pages/Container/Supervision/FireResourceStats/index.js +++ b/src/pages/Container/Supervision/FireResourceStats/index.js @@ -30,22 +30,37 @@ function FireResourceStats(props) { const renderCountLink = (text, record, type) => { const count = text || 0; - // 如果数量为0,只显示数字不可点击 + // 数量为0也保持蓝色展示 if (count === 0) { - return 0; + return ( + + 0 + + ); } return ( - handleViewDetail(record, type)} + onKeyDown={e => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + handleViewDetail(record, type); + } + }} > {count} - + ); }; @@ -109,3 +124,4 @@ function FireResourceStats(props) { } export default Connect([NS_FIRE_RESOURCE_STATS], true)(Permission(FireResourceStats)); +