需求修改

dev-tmp1
huwei 2026-08-18 19:59:28 +08:00
parent 616be6c8d8
commit 2720d55d3b
6 changed files with 119 additions and 29 deletions

BIN
.temp/backend_compile.log Normal file

Binary file not shown.

BIN
.temp/backend_compile2.log Normal file

Binary file not shown.

View File

@ -0,0 +1,42 @@
附件6
安全评价机构业务范围与设备参照表
__业务范围__
__设备类型__
__煤炭开采业__
岩土工程分析软件,矿井测风表(高、中、微速)或三合一电子风表,光学瓦检仪,多功能气体测定仪,便携式有毒有害、可燃气体检测报警仪,具有测量露天矿台阶坡面角功能的智能测距仪,地质罗盘,防爆数码照相机。
__金属、非金属矿__
__及其他矿采选业__
岩土工程分析软件,坡度规,地质罗盘,风表,风压表。
__陆地石油和__
__天然气开采业__
火灾、爆炸、扩散定量风险计算分析软件,测温仪,测厚仪,便携式有毒有害、可燃气体检测报警仪。
__陆上油气__
__管道运输业__
火灾、爆炸、扩散定量风险计算分析软件,便携式有毒有害、可燃气体检测报警仪,测温仪,测厚仪。
__石油加工业化学原料、化学品及医药制造业__
火灾、爆炸、扩散定量风险计算分析软件,测温仪,测厚仪,便携式有毒有害、可燃气体检测报警仪。
__烟花爆竹制造业__
火灾、爆炸、扩散定量风险计算分析软件,高精度温、湿度仪,手持式静电测试仪。
__金属冶炼__
多功能可燃气体检测报警仪,有毒气体检测报警仪,温、湿度仪,热辐射监测仪,经纬仪。

View File

@ -14,8 +14,8 @@ module.exports = {
// API_HOST: "http://192.168.0.134", // API_HOST: "http://192.168.0.134",
// API_HOST: "http://192.168.0.150", //太浅 // API_HOST: "http://192.168.0.150", //太浅
API_HOST: "https://gbs-gateway.qhdsafety.com", // API_HOST: "https://gbs-gateway.qhdsafety.com",
//API_HOST: "http://192.168.0.103", //huwei API_HOST: "http://192.168.0.103", //huwei
}, },
production: { production: {
// 应用后端分支名称,部署上线需要 // 应用后端分支名称,部署上线需要

View File

@ -37,8 +37,11 @@ export const equipInfoToggleStatus = declareRequest(
"Post > @/safetyEval/org-equipment/modify", "Post > @/safetyEval/org-equipment/modify",
); );
// 2026-08-18 需求变更:装备信息管理页「设备类型」不再与「业务范围」联动。
// 前端无需先选择业务范围,直接获取后端「按 device_type_code 去重后的全量设备类型清单」即可选择。
// 后端接口GET /safetyEval/org-business-scope-device-ref/device-types
export const queryDeviceTypeOptions = declareRequest( export const queryDeviceTypeOptions = declareRequest(
"equipInfoLoading", "equipInfoLoading",
"Get > /safetyEval/org-business-scope-device-ref", "Get > /safetyEval/org-business-scope-device-ref/device-types",
"deviceTypeOptions: [] | res.data || []", "deviceTypeOptions: [] | res.data || []",
); );

View File

@ -30,6 +30,16 @@ import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions";
const { router } = tools; const { router } = tools;
const DUAL_CHANNEL_MAP = { 1: "是", 2: "否" }; const DUAL_CHANNEL_MAP = { 1: "是", 2: "否" };
// 2026-08-18 需求变更:装备业务范围改为多选。搜索/筛选时把多选数组 industryCode 拼接为逗号分隔字符串,
// 便于后端以 String 接收并进行包含匹配过滤;其余字段原样透传。
function toEquipQueryParams(value = {}) {
const next = { ...value };
if (Array.isArray(next.industryCode)) {
next.industryCode = next.industryCode.join(",");
}
return next;
}
function EquipInfoPage(props) { function EquipInfoPage(props) {
const [formModalOpen, setFormModalOpen] = useState(false); const [formModalOpen, setFormModalOpen] = useState(false);
const [viewModalOpen, setViewModalOpen] = useState(false); const [viewModalOpen, setViewModalOpen] = useState(false);
@ -47,7 +57,12 @@ function EquipInfoPage(props) {
}; };
useEffect(() => { useEffect(() => {
searchForm.setFieldsValue(router.query); // 2026-08-18 需求变更:业务范围多选。首次从 URL 恢复搜索条件时,把逗号串拆为数组回显到多选控件
const query = toEquipQueryParams(router.query);
if (query.industryCode) {
query.industryCode = String(query.industryCode).split(",").filter(Boolean);
}
searchForm.setFieldsValue(query);
handleSearch(); handleSearch();
}, []); }, []);
@ -120,21 +135,24 @@ function EquipInfoPage(props) {
/> />
</Form.Item>, </Form.Item>,
<Form.Item key="industryCode" name="industryCode"> <Form.Item key="industryCode" name="industryCode">
{/* 2026-08-18 需求变更:装备业务范围改为可多选。搜索区多选后以逗号拼接提交给后端进行包含匹配过滤 */}
<ControlWrapper.Select <ControlWrapper.Select
label="业务范围" label="业务范围"
placeholder="请选择" placeholder="请选择"
allowClear allowClear
mode="multiple"
maxTagCount="responsive"
style={{ width: "100%" }} style={{ width: "100%" }}
options={QUALIFICATION_INDUSTRY_OPTIONS} options={QUALIFICATION_INDUSTRY_OPTIONS}
/> />
</Form.Item>, </Form.Item>,
]} ]}
onReset={(value) => { onReset={(value) => {
router.query = { ...value, current: 1, size: 10 }; router.query = { ...toEquipQueryParams(value), current: 1, size: 10 };
handleSearch(); handleSearch();
}} }}
onFinish={(value) => { onFinish={(value) => {
router.query = { ...value, current: 1, size: 10 }; router.query = { ...toEquipQueryParams(value), current: 1, size: 10 };
handleSearch(); handleSearch();
}} }}
/> />
@ -149,12 +167,20 @@ function EquipInfoPage(props) {
}, },
{ title: "设备型号", dataIndex: "deviceModel", ellipsis: true }, { title: "设备型号", dataIndex: "deviceModel", ellipsis: true },
{ {
// 2026-08-18 需求变更:装备业务范围改为多选,后端 industry_code 以逗号分隔存储。
// 此处将逗号串拆分为多个标签展示,兼容单值与多值。
title: "业务范围", title: "业务范围",
dataIndex: "industryCode", dataIndex: "industryCode",
render: (v) => render: (v) => {
QUALIFICATION_INDUSTRY_OPTIONS.find((o) => o.value === v) if (!v) return "-";
?.label ?? const codes = String(v).split(",").filter(Boolean);
(v || "-"), const labels = codes.map(
(c) =>
QUALIFICATION_INDUSTRY_OPTIONS.find((o) => o.value === c)
?.label ?? c,
);
return labels.length > 1 ? labels.join("、") : labels[0] || "-";
},
}, },
{ title: "设备类型", dataIndex: "deviceTypeName" }, { title: "设备类型", dataIndex: "deviceTypeName" },
{ {
@ -284,25 +310,21 @@ function EquipFormModal({
const [detailLoading, setDetailLoading] = useState(false); const [detailLoading, setDetailLoading] = useState(false);
const [deviceTypeOptions, setDeviceTypeOptions] = useState([]); const [deviceTypeOptions, setDeviceTypeOptions] = useState([]);
const [deviceTypeLoading, setDeviceTypeLoading] = useState(false); const [deviceTypeLoading, setDeviceTypeLoading] = useState(false);
const industryCode = Form.useWatch("industryCode", form); // 2026-08-18 需求变更:设备类型与业务范围解耦,不再监听 industryCode。
// 设备类型清单在弹窗打开时一次性加载(去重后的全量数据),无需先选业务范围。
useEffect(() => { useEffect(() => {
if (!industryCode) { // 仅在弹窗打开时加载一次设备类型全量清单,避免重复请求
setDeviceTypeOptions([]); if (!open) return;
form.resetFields(["deviceTypeCode"]);
return;
}
let cancelled = false; let cancelled = false;
setDeviceTypeLoading(true); setDeviceTypeLoading(true);
queryDeviceTypeOptions({ industryCode, pageSize: 999 }) // 调用后端去重接口 GET /safetyEval/org-business-scope-device-ref/device-types
queryDeviceTypeOptions({})
.then((res) => { .then((res) => {
if (cancelled) return; if (cancelled) return;
const list = res?.data || []; const list = res?.data || [];
const unique = Array.from(
new Map(list.map((item) => [item.deviceTypeCode, item])).values(),
);
setDeviceTypeOptions( setDeviceTypeOptions(
unique.map((item) => ({ list.map((item) => ({
label: item.deviceTypeName, label: item.deviceTypeName,
value: item.deviceTypeCode, value: item.deviceTypeCode,
})), })),
@ -314,7 +336,7 @@ function EquipFormModal({
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [industryCode]); }, [open]);
useEffect(() => { useEffect(() => {
if (!open) return; if (!open) return;
@ -328,6 +350,12 @@ function EquipFormModal({
.then((res) => { .then((res) => {
if (cancelled) return; if (cancelled) return;
const data = res?.data || {}; const data = res?.data || {};
// 2026-08-18 需求变更:业务范围改为多选。回显时把后端的逗号分隔串拆分为数组,适配 multiple Select
if (data.industryCode) {
data.industryCode = String(data.industryCode).split(",").filter(Boolean);
} else {
data.industryCode = [];
}
form.setFieldsValue(data); form.setFieldsValue(data);
}) })
.finally(() => { .finally(() => {
@ -343,10 +371,17 @@ function EquipFormModal({
onCancel(); onCancel();
}; };
// 2026-08-18 需求变更:装备业务范围改为多选。提交时多选数组以逗号拼接为字符串传给后端(后端字段仍为 String
const handleSubmit = async (values) => { const handleSubmit = async (values) => {
try { try {
setSubmitting(true); setSubmitting(true);
if (currentId) values.id = currentId; if (currentId) values.id = currentId;
// 多选数组 -> 逗号分隔字符串;为空时置空字符串,避免后端存 null
if (Array.isArray(values.industryCode)) {
values.industryCode = values.industryCode.join(",");
} else if (values.industryCode === undefined || values.industryCode === null) {
values.industryCode = "";
}
const res = await (currentId const res = await (currentId
? equipInfoEdit(values) ? equipInfoEdit(values)
: equipInfoAdd(values)); : equipInfoAdd(values));
@ -393,13 +428,16 @@ function EquipFormModal({
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
{/* 2026-08-18 需求变更:装备业务范围改为可多选。提交前将多选数组以逗号拼接为字符串入库,回显时拆分。 */}
<Form.Item <Form.Item
name="industryCode" name="industryCode"
label="业务范围" label="业务范围"
rules={[{ required: true, message: "请选择业务范围" }]} rules={[{ required: true, message: "请选择业务范围" }]}
> >
<Select <Select
placeholder="请选择业务范围" placeholder="请选择业务范围(可多选)"
mode="multiple"
maxTagCount="responsive"
options={QUALIFICATION_INDUSTRY_OPTIONS} options={QUALIFICATION_INDUSTRY_OPTIONS}
allowClear allowClear
/> />
@ -412,10 +450,9 @@ function EquipFormModal({
rules={[{ required: true, message: "请选择设备类型" }]} rules={[{ required: true, message: "请选择设备类型" }]}
> >
<Select <Select
placeholder="请先选择业务范围" placeholder="请选择设备类型"
loading={deviceTypeLoading} loading={deviceTypeLoading}
options={deviceTypeOptions} options={deviceTypeOptions}
disabled={!industryCode}
allowClear allowClear
showSearch showSearch
onChange={(value, option)=>{ onChange={(value, option)=>{
@ -566,10 +603,18 @@ export function EquipViewModal({ open, currentId, equipInfoGet, onCancel }) {
{info.deviceModel} {info.deviceModel}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="业务范围"> <Descriptions.Item label="业务范围">
{QUALIFICATION_INDUSTRY_OPTIONS.find( {/* 2026-08-18 需求变更:业务范围改为多选,展示时拆分逗号串 */}
(o) => o.value === info.industryCode, {info.industryCode
)?.label ?? ? String(info.industryCode)
(info.industryCode || "-")} .split(",")
.filter(Boolean)
.map(
(c) =>
QUALIFICATION_INDUSTRY_OPTIONS.find((o) => o.value === c)
?.label ?? c,
)
.join("、")
: "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="设备类型"> <Descriptions.Item label="设备类型">
{info.deviceTypeName || "-"} {info.deviceTypeName || "-"}