From fb033ada287e2450d73ec50e3f6bb497881d8071 Mon Sep 17 00:00:00 2001 From: zty Date: Fri, 10 Jul 2026 04:32:35 -0400 Subject: [PATCH] =?UTF-8?q?feat(ms):=20=E7=AE=A1=E7=90=86=E7=AB=AF?= =?UTF-8?q?=E6=9D=90=E6=96=99=E5=BA=93=E6=8E=92=E5=BA=8F=E4=BE=9D=E6=8D=AE?= =?UTF-8?q?/=E5=88=86=E7=BB=84=20+=20=E5=81=A5=E5=BA=B7=E6=A1=A3=E6=A0=87?= =?UTF-8?q?=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Material 类型新增 ypt/health_tier 字段 - material.ts search() 查询参数补 group_by_tier - material-card 新增排序依据 Select(手动排序/综合 Ypt/五种污染物释放量)与按健康档分组 Switch, 健康档 Tag 列,分组时按档打分区标题 - 顶部排序依据 Select 为唯一排序权威来源:移除旧筛选区排序下拉对 searchParams 第三参数的驱动, 避免其静默覆盖新排序请求(对齐用户端 iapip-web 同一修复) - 经核查 ms 端不存在手动拖动/位置输入重排 sort_order 的既有功能,故无需像 web 端那样额外加 sortKey==='sort_order' && !groupByTier 门控 Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01VCShKevM5prWZhp1kk1iGh --- .../管理端/iapip-ms/src/common/types.ts | 298 ++++++++++ .../src/components/material-card/index.tsx | 546 ++++++++++++++++++ .../iapip-ms/src/services/api/material.ts | 156 +++++ 3 files changed, 1000 insertions(+) create mode 100644 空气质量预测/源码/管理端/iapip-ms/src/common/types.ts create mode 100644 空气质量预测/源码/管理端/iapip-ms/src/components/material-card/index.tsx create mode 100644 空气质量预测/源码/管理端/iapip-ms/src/services/api/material.ts diff --git a/空气质量预测/源码/管理端/iapip-ms/src/common/types.ts b/空气质量预测/源码/管理端/iapip-ms/src/common/types.ts new file mode 100644 index 0000000..395d169 --- /dev/null +++ b/空气质量预测/源码/管理端/iapip-ms/src/common/types.ts @@ -0,0 +1,298 @@ +export type AnyObj = { + [key: string]: any +} + +export type Arrayable = T | T[] + +/** + * Server Types + */ + +export type Admin = { + id: string + name: string + password: string + username: string + status: number + type: ADMIN_TYPE + authz_hist_mgmt: number + authz_tmpl_mgmt: number + authz_mtrl_mgmt: number + authz_audit_mgmt: number + authz_acct_mgmt: number + authz_sys_cfg: number + creator_id: string + creator_name: string + created_at: string + updated_at: string +} + +export enum ADMIN_TYPE { + SUPER_ADMIN = 1, + ADMIN = 2 +} + +export type User = { + id: string + name: string + password: string + username: string + status: number + creator_id: string + creator_name: string + created_at: string + updated_at: string +} + +export type AdminCert = { + id: string + name: string + username: string + status: number + type: ADMIN_TYPE + authz_hist_mgmt: number + authz_tmpl_mgmt: number + authz_mtrl_mgmt: number + authz_audit_mgmt: number + authz_acct_mgmt: number + authz_sys_cfg: number + ip: string + login_at: Date + expire_at: Date + iat?: number + exp?: number +} + +export type Creator = { + id: string + name: string + username: string +} + +export type Project = { + id: string + name: string + category?: string + province?: string + city?: string + climatic_zone?: string + constr_area?: number + usage_area?: number + spaces?: Space[] + status?: number + display?: number + predicted_at?: string + score?: number + grade?: number + collectors?: { user_id: string; project_id: string }[] + from?: FROM_TYPE + creator_id?: string + creator_name: string + creator?: Creator + related_user?: Creator + related_admin?: Creator + created_at: string + updated_at: string +} + +export type Space = { + id: string + project_id: string + name: string + category?: string + layout: number + height?: number + area?: number + volume?: number + env_temp?: number + env_hum?: number + env_vent_rate?: number + apc_lmt_std_id?: string + apc_lmt_std?: ApcLimitStandard + materials?: Material[] + methanal_c?: number + tvoc_c?: number + benzene_c?: number + toluene_c?: number + p_xylene_c?: number + methanal_c_exceed?: number + tvoc_c_exceed?: number + benzene_c_exceed?: number + toluene_c_exceed?: number + p_xylene_c_exceed?: number + creator_id: string + creator_name: string + created_at: string + updated_at: string +} + +export type Material = { + id?: number + material_id: string + project_id?: string + space_id?: string + name?: string + category?: string + brand?: string + factory?: string + spec?: string + eco_level?: ECO_LEVEL + unit?: MTRL_UNIT + qty?: number + display?: number + ypt?: number | null + health_tier?: 'A' | 'B' | 'C' | null + collectors?: { user_id: string; project_id: string }[] + methanal?: number + methanal_min_be?: number + methanal_be_area?: number + methanal_be_roc?: number + tvoc?: number + tvoc_min_be?: number + tvoc_be_area?: number + tvoc_be_roc?: number + benzene?: number + benzene_min_be?: number + benzene_be_area?: number + benzene_be_roc?: number + toluene?: number + toluene_min_be?: number + toluene_be_area?: number + toluene_be_roc?: number + p_xylene?: number + p_xylene_min_be?: number + p_xylene_be_area?: number + p_xylene_be_roc?: number + methanal_cr?: number + tvoc_cr?: number + benzene_cr?: number + toluene_cr?: number + p_xylene_cr?: number + methanal_cr_exceed?: number + tvoc_cr_exceed?: number + benzene_cr_exceed?: number + toluene_cr_exceed?: number + p_xylene_cr_exceed?: number + is_methanal_ps?: number + is_tvoc_ps?: number + is_benzene_ps?: number + is_toluene_ps?: number + is_p_xylene_ps?: number + from?: FROM_TYPE + user_id: string + user_name: string + creator_id?: string + creator_name: string + creator?: Creator + related_user?: Creator + related_admin?: Creator + created_at: string + updated_at: string +} + +export type AuditRequest = { + id: string + status: AUDIT_REQ_STATUS + source_id?: string + source_creator_id?: string + source: AUDIT_REQ_SRC + type: AUDIT_REQ_TYPE + desc?: string + remark?: string + details: AuditRequestDetails[] + auditor_id?: string + auditor_name?: string + auditor?: Creator + audited_at?: string + creator_id?: string + creator_name: string + creator?: Creator + created_at: string + updated_at: string +} + +export type AuditRequestDetails = { + id: number + audit_request_id: number + content: AnyObj +} + +export enum ECO_LEVEL { + E0 = 'E0', + E1 = 'E1', + E2 = 'E2' +} + +export enum MTRL_UNIT { + AREA = 'AREA', + LEN = 'LEN' +} + +export enum FROM_TYPE { + CREATE = 'CREATE', + IMPORT = 'IMPORT', + COLLECT = 'COLLECT' +} + +export enum AUDIT_REQ_SRC { + PUB_TEMP = 'PUB_TEMP', + SELF_TEMP = 'SELF_TEMP', + PUB_MTRL = 'PUB_MTRL', + SELF_MTRL = 'SELF_MTRL', + HIS_PROJ = 'HIS_PROJ' +} + +export enum AUDIT_REQ_TYPE { + CREATE = 'CREATE', + IMPORT = 'IMPORT', + UPDATE = 'UPDATE', + DELETE = 'DELETE', + COLLECT = 'COLLECT', + EXPORT = 'EXPORT' +} + +export enum AUDIT_REQ_STATUS { + REJECT = -1, + HOLD = 0, + PASS = 1 +} + +export type ProjectSpaceCategory = { + pry_no_1: number + project_category: string + space_categories: { + pry_no_2: number + space_category: string + }[] +} + +export type MaterialCategory = { + pry_no_1: number + first_category: string + second_categories: { + pry_no_2: number + second_category: string + unit?: MTRL_UNIT + }[] +} + +export type CityInformation = { + pry_no_1: number + province: string + cities: { + pry_no_2: number + city: string + climatic_zone?: string + env_temp: number + env_hum: number + }[] +} + +export type ApcLimitStandard = { + id: string + methanal_c_lmt: number + tvoc_c_lmt: number + benzene_c_lmt: number + toluene_c_lmt: number + p_xylene_c_lmt: number +} diff --git a/空气质量预测/源码/管理端/iapip-ms/src/components/material-card/index.tsx b/空气质量预测/源码/管理端/iapip-ms/src/components/material-card/index.tsx new file mode 100644 index 0000000..be0a67d --- /dev/null +++ b/空气质量预测/源码/管理端/iapip-ms/src/components/material-card/index.tsx @@ -0,0 +1,546 @@ +import { DATA_TYPE } from '@/common/constants' +import { AnyObj, ECO_LEVEL, Material } from '@/common/types' +import { searchParams } from '@/common/utils' +import api from '@/services/api' +import { + ActionType, + LightFilter, + ProFormCascader, + ProFormSelect, + ProFormText, + ProTable +} from '@ant-design/pro-components' +import { Badge, Button, Form, Modal, Select, Switch, Tag } from 'antd' +import { useRef, useState } from 'react' +import OperateMaterial from '../apply-request-modal/operate-material' +import ImportMaterialsModal from '../import-file-modal/materials' +import MaterialModalForm from '../material-modal-form' +import PageCard from '../page-card' + +const MaterialCard: React.FC<{ + title?: string + modal?: boolean + modalProps?: { + open?: boolean + onCancel?: () => void + } + defaultSelected?: Material[] + onAdd?: (addedMtrls?: Material[]) => void +}> = ({ title, modal, modalProps, defaultSelected, onAdd }) => { + const [tab, setTab] = useState(DATA_TYPE.PUBLIC) + const tableRef = useRef() + const [filterForm] = Form.useForm() + const [filterConditions, setFilterConditions] = useState() + const [openCreateModal, setOpenCreateModal] = useState(false) + const [details, setDetails] = useState() + const [selected, setSelected] = useState() + const [content, setContent] = useState() + // 材料排序依据(默认综合 Ypt 升序)与是否按健康档分组显示 + const [sortKey, setSortKey] = useState('ypt') + const [groupByTier, setGroupByTier] = useState(false) + const page = ( + setTab(key as DATA_TYPE) : undefined} + extra={ + !modal && tab === DATA_TYPE.PUBLIC + ? [ + 导入材料} + />, + <> + + setOpenCreateModal(false)} + onFinish={async (data) => setContent(data)} + /> + + ] + : [] + } + cardStyle={ + modal + ? { + borderBottomWidth: 0 + } + : undefined + } + > +
+
+ setFilterConditions(data)}> + + + { + const cats = await api.config.getMtrlCatList() + return cats.map((item) => ({ + value: item.first_category, + label: item.first_category, + children: item.second_categories.map((c) => ({ + value: c.second_category, + label: c.second_category + })) + })) + }} + transform={(val) => ({ category: val.map((v: string[]) => v.join('/')) })} + /> + + + + + {tab === DATA_TYPE.PRIVATE ? ( + + ) : ( + + )} + + +
+
+ +
+
+
+ + 排序依据{' '} +