Merge remote-tracking branch 'origin/dev' into dev
commit
ecd3573a78
|
|
@ -4,6 +4,7 @@
|
||||||
/node_modules
|
/node_modules
|
||||||
|
|
||||||
# production
|
# production
|
||||||
|
/prototype
|
||||||
/dist
|
/dist
|
||||||
/demo
|
/demo
|
||||||
/.trae/
|
/.trae/
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,51 @@
|
||||||
* 全局常量定义
|
* 全局常量定义
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export {};
|
/** 证书状态 */
|
||||||
|
export const CERT_STATUS_MAP = {
|
||||||
|
normal: { label: "正常", color: "success" },
|
||||||
|
expiring: { label: "即将到期", color: "warning" },
|
||||||
|
expired: { label: "已过期", color: "error" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 核验状态 */
|
||||||
|
export const VERIFY_STATUS_MAP = {
|
||||||
|
pending: { label: "待确认", color: "warning" },
|
||||||
|
passed: { label: "确认通过", color: "success" },
|
||||||
|
rejected: { label: "打回", color: "error" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 审核状态 */
|
||||||
|
export const REVIEW_STATUS_MAP = {
|
||||||
|
pending: { label: "待审核", color: "warning" },
|
||||||
|
reviewing: { label: "审核中", color: "processing" },
|
||||||
|
rejected: { label: "打回", color: "error" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 专家核验状态 */
|
||||||
|
export const EXPERT_STATUS_MAP = {
|
||||||
|
pending: { label: "待核验", color: "blue" },
|
||||||
|
arranging: { label: "待安排", color: "warning" },
|
||||||
|
passed: { label: "已核验", color: "success" },
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 公示状态 */
|
||||||
|
export const PUBLICITY_STATUS_MAP = {
|
||||||
|
pending: { label: "待公示", color: "warning" },
|
||||||
|
published: { label: "已公示", color: "success" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 变更状态 */
|
||||||
|
export const CHANGE_STATUS_MAP = {
|
||||||
|
stuck: { label: "停滞中", color: "error" },
|
||||||
|
pending: { label: "待审核", color: "warning" },
|
||||||
|
approved: { label: "已审核", color: "success" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 专家等级 */
|
||||||
|
export const EXPERT_LEVEL_MAP = {
|
||||||
|
1: "一级",
|
||||||
|
2: "二级",
|
||||||
|
3: "三级",
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ import { getFileUrlFromServer } from "zy-react-library/utils";
|
||||||
import "dayjs/locale/zh-cn";
|
import "dayjs/locale/zh-cn";
|
||||||
import "../blessed_by_buddha";
|
import "../blessed_by_buddha";
|
||||||
|
|
||||||
require("antd/dist/reset.css");
|
|
||||||
require("zy-react-library/css/common.less");
|
|
||||||
|
|
||||||
dayjs.locale("zh-cn");
|
dayjs.locale("zh-cn");
|
||||||
setJJBCommonAntdMessage(message);
|
setJJBCommonAntdMessage(message);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,213 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Button, Form, Select, Space, Table, Tag } from "antd";
|
||||||
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
|
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
||||||
|
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||||
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
|
import {tools} from '@cqsjjb/jjb-common-lib'
|
||||||
|
import { VERIFY_STATUS_MAP } from "~/enumerate/constant";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 静态模拟数据
|
||||||
|
const MOCK_DATA = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
orgName: "重庆安评技术研究院有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2026-001",
|
||||||
|
businessScope: "化工, 石油加工",
|
||||||
|
confirmStatus: "pending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
orgName: "北京中安评价中心(重庆分公司)",
|
||||||
|
orgType: "异地机构",
|
||||||
|
certNo: "API-2026-015",
|
||||||
|
businessScope: "矿山",
|
||||||
|
confirmStatus: "passed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
orgName: "重庆华安评价有限公司",
|
||||||
|
orgType: "异地机构",
|
||||||
|
certNo: "API-2025-088",
|
||||||
|
businessScope: "石油加工",
|
||||||
|
confirmStatus: "pending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
orgName: "重庆安评科技有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2024-056",
|
||||||
|
businessScope: "化工",
|
||||||
|
confirmStatus: "rejected",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
orgName: "重庆恒安安全评价有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2025-032",
|
||||||
|
businessScope: "矿山, 石油加工",
|
||||||
|
confirmStatus: "passed",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const {router} = tools;
|
||||||
|
|
||||||
|
const ExpertVerification = (props) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
setLoading(true);
|
||||||
|
console.log(router.query);
|
||||||
|
setTimeout(() => setLoading(false), 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = (values) => {
|
||||||
|
setLoading(true);
|
||||||
|
router.query={
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
}
|
||||||
|
handleSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.setFieldsValue(router.query);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "序号",
|
||||||
|
dataIndex: "id",
|
||||||
|
width: 60,
|
||||||
|
fixed: "left",
|
||||||
|
render: (text, record, index) => index + 1,
|
||||||
|
},
|
||||||
|
{ title: "机构名称", dataIndex: "orgName", width: 220, ellipsis: true },
|
||||||
|
{ title: "机构类型", dataIndex: "orgType", width: 100 },
|
||||||
|
{ title: "证书编号", dataIndex: "certNo", width: 140, ellipsis: true },
|
||||||
|
{ title: "安全评价业务范围", dataIndex: "businessScope", width: 180, ellipsis: true },
|
||||||
|
{
|
||||||
|
title: "确认状态",
|
||||||
|
dataIndex: "confirmStatus",
|
||||||
|
width: 100,
|
||||||
|
render: (status) => {
|
||||||
|
const config = VERIFY_STATUS_MAP[status];
|
||||||
|
return config ? <Tag color={config.color}>{config.label}</Tag> : status;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
width: 140,
|
||||||
|
fixed: "right",
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space>
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`FilingDetail?id=${record.id}`)}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
{record.confirmStatus === "pending" && (
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`QualReviewForm?id=${record.id}`)}>
|
||||||
|
核验
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageLayout title="专家资料核验">
|
||||||
|
|
||||||
|
<SearchForm
|
||||||
|
style={{ marginBottom: 24 }}
|
||||||
|
form={form}
|
||||||
|
loading={loading}
|
||||||
|
formLine={[
|
||||||
|
<Form.Item key="orgName" name="orgName">
|
||||||
|
<ControlWrapper.Input label="机构名称" placeholder="请输入" allowClear />
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="orgType" name="orgType">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="机构类型"
|
||||||
|
placeholder="请输入"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="本地机构">本地机构</Select.Option>
|
||||||
|
<Select.Option value="异地机构">异地机构</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item
|
||||||
|
key="businessScope"
|
||||||
|
name="businessScope"
|
||||||
|
>
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="安全评价业务范围"
|
||||||
|
placeholder="请输入"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="石油加工">石油加工</Select.Option>
|
||||||
|
<Select.Option value="化工">化工</Select.Option>
|
||||||
|
<Select.Option value="矿山">矿山</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="confirmStatus" name="confirmStatus">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="确认状态"
|
||||||
|
placeholder="请输入"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="pending">待确认</Select.Option>
|
||||||
|
<Select.Option value="passed">确认通过</Select.Option>
|
||||||
|
<Select.Option value="rejected">打回</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
]}
|
||||||
|
onReset={handleReset}
|
||||||
|
onFinish={(values) => {
|
||||||
|
router.query={
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
}
|
||||||
|
handleSearch();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
rowKey="id"
|
||||||
|
columns={columns}
|
||||||
|
dataSource={MOCK_DATA}
|
||||||
|
scroll={{ y: props.scrollY }}
|
||||||
|
loading={loading}
|
||||||
|
pagination={{
|
||||||
|
total: MOCK_DATA.length,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showTotal: (total) => `共 ${total} 条`,
|
||||||
|
current: router.query.current,
|
||||||
|
pageSize: router.query.pageSize,
|
||||||
|
onChange: (page, pageSize) => {
|
||||||
|
|
||||||
|
router.query={
|
||||||
|
...router.query,
|
||||||
|
current: page,
|
||||||
|
pageSize,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AntdTableFuncControl(ExpertVerification);
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import React, { useMemo } from "react";
|
||||||
|
import { Tag, Space } from "antd";
|
||||||
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
|
import { REVIEW_STATUS_MAP } from "~/enumerate/constant";
|
||||||
|
import { MOCK_DETAIL } from "../mockData";
|
||||||
|
import FilingTabs from "../FilingTabs";
|
||||||
|
|
||||||
|
function parseQueryId(location) {
|
||||||
|
const search = location?.search || window.location.search || "";
|
||||||
|
return new URLSearchParams(search).get("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
const FilingDetail = (props) => {
|
||||||
|
const id = useMemo(() => parseQueryId(props.location), [props.location?.search]);
|
||||||
|
const detail = MOCK_DETAIL;
|
||||||
|
const statusConfig = REVIEW_STATUS_MAP[detail.reviewStatus];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageLayout
|
||||||
|
title={
|
||||||
|
<Space>
|
||||||
|
<span>备案申请详情</span>
|
||||||
|
{statusConfig && <Tag color={statusConfig.color}>{statusConfig.label}</Tag>}
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
history={props.history}
|
||||||
|
previous
|
||||||
|
>
|
||||||
|
<FilingTabs detail={detail} />
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilingDetail;
|
||||||
|
|
@ -0,0 +1,255 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { Button, Descriptions, Table, Tag, Tabs, Select, Modal, Space } from "antd";
|
||||||
|
import {
|
||||||
|
MOCK_MATERIALS,
|
||||||
|
MOCK_PERSONNEL,
|
||||||
|
MOCK_EQUIPMENT,
|
||||||
|
MOCK_EQUIP_DETAIL,
|
||||||
|
MOCK_PERSONNEL_DETAIL,
|
||||||
|
MOCK_CERTIFICATES,
|
||||||
|
CALIBRATION_MAP,
|
||||||
|
} from "../mockData";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 共享组件:资质备案 5 个标签页(详情 / 审核共用)
|
||||||
|
* @param {Object} props
|
||||||
|
* @param {Object} props.detail - 备案详情数据
|
||||||
|
* @param {boolean} [props.isReview=false] - 审核模式(开启后材料上传显示"上传附件"+"符合性"列)
|
||||||
|
* @param {Object} [props.compliance={}] - 审核模式下的符合性状态
|
||||||
|
* @param {Function} [props.onComplianceChange] - 符合性变动回调
|
||||||
|
* @param {Function} [props.onPersonnelView] - 查看人员详情回调(覆盖默认弹窗)
|
||||||
|
* @param {Function} [props.onEquipView] - 查看设备详情回调 (record) => void(覆盖默认弹窗)
|
||||||
|
*/
|
||||||
|
const FilingTabs = ({
|
||||||
|
detail,
|
||||||
|
isReview = false,
|
||||||
|
compliance = {},
|
||||||
|
onComplianceChange,
|
||||||
|
onPersonnelView,
|
||||||
|
onEquipView,
|
||||||
|
}) => {
|
||||||
|
const [personnelVisible, setPersonnelVisible] = useState(false);
|
||||||
|
const [equipVisible, setEquipVisible] = useState(false);
|
||||||
|
const [selectedEquip, setSelectedEquip] = useState(null);
|
||||||
|
|
||||||
|
const baseCols = [
|
||||||
|
{ title: "序号", width: 60, render: (_, __, i) => i + 1 },
|
||||||
|
{ title: "材料名称", dataIndex: "name" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const materialCols = isReview
|
||||||
|
? [
|
||||||
|
...baseCols,
|
||||||
|
{ title: "上传附件", dataIndex: "attachment", width: 120 },
|
||||||
|
{ title: "格式", dataIndex: "format", width: 80 },
|
||||||
|
{ title: "状态", dataIndex: "status", width: 100, render: () => <Tag color="success">已上传</Tag> },
|
||||||
|
{ title: "符合性", width: 100,
|
||||||
|
render: (_, record) => (
|
||||||
|
<Select
|
||||||
|
style={{ width: "100%", fontSize: "0.75rem" }}
|
||||||
|
size="small"
|
||||||
|
placeholder="请选择"
|
||||||
|
value={compliance[record.id]}
|
||||||
|
onChange={(v) => onComplianceChange?.(record.id, v)}
|
||||||
|
>
|
||||||
|
<Select.Option value="pass">符合</Select.Option>
|
||||||
|
<Select.Option value="fail">不符合</Select.Option>
|
||||||
|
</Select>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
...baseCols,
|
||||||
|
{ title: "格式", dataIndex: "format", width: 80 },
|
||||||
|
{ title: "状态", dataIndex: "status", width: 100, render: () => <Tag color="success">已上传</Tag> },
|
||||||
|
{ title: "操作", width: 80, render: () => <Button type="link" size="small">预览</Button> },
|
||||||
|
];
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
key: "info",
|
||||||
|
label: "1.备案基本信息",
|
||||||
|
children: (
|
||||||
|
<Descriptions column={2} bordered size="small" style={{ background: "#fff" }}>
|
||||||
|
<Descriptions.Item label="申请的业务范围" span={2}>{detail.scopeName}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="备案属地">{detail.filingRegion}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="备案单位">{detail.orgName}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="备案单位类型">{detail.orgType}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="统一社会信用代码">{detail.creditCode}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="办公地址" span={2}>{detail.officeAddress}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="注册地址" span={2}>{detail.registerAddress}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="资质证书编号">{detail.certNo}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="信息公开网址">{detail.website}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="法人代表及电话">{detail.legalPerson} / {detail.legalPhone}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="联系人及电话">{detail.contactPerson} / {detail.contactPhone}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="固定资产总值(万元)">{detail.fixedAssets}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="工作场所建筑面积">{detail.officeArea}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="档案室面积">{detail.archiveArea}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="专职安全评价师数量">{detail.evaluatorCount}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="注册安全工程师数量">{detail.registerEngineerCount}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="单位基本情况介绍" span={2}>{detail.description}</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "materials",
|
||||||
|
label: "2.备案材料上传",
|
||||||
|
children: (
|
||||||
|
<Table size="small" bordered rowKey="id" pagination={false} dataSource={MOCK_MATERIALS} columns={materialCols} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "promise",
|
||||||
|
label: "3.法定代表人承诺书",
|
||||||
|
children: (
|
||||||
|
<div style={{ border: "1px solid #d9d9d9", borderRadius: 6, padding: "1.25rem 1.5rem", background: "#fafafa", fontSize: "0.85rem", lineHeight: 1.9 }}>
|
||||||
|
<p style={{ textAlign: "center", fontWeight: 600, fontSize: "0.95rem", marginBottom: "0.75rem" }}>申请单位法定代表人承诺书</p>
|
||||||
|
<p>本人{detail.legalPerson}是{detail.orgName}法定代表人,现代表我单位承诺如下:</p>
|
||||||
|
<p>一、我单位自愿申请安全评价机构资质。本人已经认真学习、了解并掌握《安全生产法》《行政许可法》《行政处罚法》及《安全评价检测检验机构管理办法》等法律法规的相关规定,知悉开展安全评价工作的法律责任、义务、权力和风险。</p>
|
||||||
|
<p>二、本人承诺本单位满足《安全评价检测检验机构管理办法》所规定的资质条件要求,本人及单位三年内无重大违法失信行为,申请资质所提交的有关材料真实、合法、有效,并对其真实性、合法性承担相应法律责任,接受并配合有关部门对本单位开展的专业能力审查。</p>
|
||||||
|
<p>三、如能获准资质,本单位将严格按照法律法规、规章标准的要求开展安全评价活动,遵守执业准则和职业道德,并对作出的安全评价报告结果承担法律责任,自觉接受应急管理部门、煤矿安全监督管理部门等行政执法部门的监督检查。</p>
|
||||||
|
<p style={{ marginTop: "0.75rem" }}>法定代表人:{detail.legalPerson}(已签名)</p>
|
||||||
|
<p>(单位盖章)</p>
|
||||||
|
<p style={{ textAlign: "right" }}>2026年06月25日</p>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "personnel",
|
||||||
|
label: "4.备案人员管理",
|
||||||
|
children: (
|
||||||
|
<Table size="small" bordered rowKey="id" pagination={false} dataSource={MOCK_PERSONNEL}
|
||||||
|
columns={[
|
||||||
|
{ title: "序号", width: 60, render: (_, __, i) => i + 1 },
|
||||||
|
{ title: "人员姓名", dataIndex: "name", width: 100 },
|
||||||
|
{ title: "类型", dataIndex: "type", width: 100 },
|
||||||
|
{ title: "职务", dataIndex: "position", width: 120 },
|
||||||
|
{ title: "职称", dataIndex: "title", width: 100 },
|
||||||
|
{ title: "专业能力", dataIndex: "ability" },
|
||||||
|
{ title: "操作", width: 80,
|
||||||
|
render: () => (
|
||||||
|
<Button type="link" size="small" onClick={onPersonnelView || (() => setPersonnelVisible(true))}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "equipment",
|
||||||
|
label: "5.装备清单",
|
||||||
|
children: (
|
||||||
|
<Table size="small" bordered rowKey="id" pagination={false} dataSource={MOCK_EQUIPMENT}
|
||||||
|
columns={[
|
||||||
|
{ title: "序号", width: 60, render: (_, __, i) => i + 1 },
|
||||||
|
{ title: "装备名称", dataIndex: "name", width: 140 },
|
||||||
|
{ title: "规格型号", dataIndex: "model", width: 120 },
|
||||||
|
{ title: "生产厂家", dataIndex: "manufacturer", width: 140 },
|
||||||
|
{ title: "计量检定情况", dataIndex: "calibration", width: 120,
|
||||||
|
render: (s) => {
|
||||||
|
const cfg = CALIBRATION_MAP[s];
|
||||||
|
return cfg ? <Tag color={cfg.color}>{cfg.label}</Tag> : s;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ title: "操作", width: 80,
|
||||||
|
render: (_, record) => (
|
||||||
|
<Button type="link" size="small" onClick={() => onEquipView ? onEquipView(record) : (setSelectedEquip(record), setEquipVisible(true))}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Tabs items={items} />
|
||||||
|
|
||||||
|
{/* 人员详细信息弹窗 */}
|
||||||
|
<Modal
|
||||||
|
title="人员详细信息"
|
||||||
|
open={personnelVisible}
|
||||||
|
onCancel={() => setPersonnelVisible(false)}
|
||||||
|
width={720}
|
||||||
|
footer={(originNode, { CancelBtn }) => <CancelBtn />}
|
||||||
|
>
|
||||||
|
<Descriptions column={2} bordered size="small">
|
||||||
|
<Descriptions.Item label="姓名">{MOCK_PERSONNEL_DETAIL.name}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="性别">{MOCK_PERSONNEL_DETAIL.gender}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="资质范围">{MOCK_PERSONNEL_DETAIL.qualScope}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="出生日期">{MOCK_PERSONNEL_DETAIL.birthDate}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="办公地址" span={2}>{MOCK_PERSONNEL_DETAIL.officeAddress}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="专业">{MOCK_PERSONNEL_DETAIL.major}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="职业等级及证书编号">{MOCK_PERSONNEL_DETAIL.certLevel}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="邮箱">{MOCK_PERSONNEL_DETAIL.email}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="人员类型">{MOCK_PERSONNEL_DETAIL.personnelType}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="身份证号">{MOCK_PERSONNEL_DETAIL.idCard}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="现住地址" span={2}>{MOCK_PERSONNEL_DETAIL.currentAddress}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="学历">{MOCK_PERSONNEL_DETAIL.education}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="毕业院校">{MOCK_PERSONNEL_DETAIL.graduateSchool}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="职务">{MOCK_PERSONNEL_DETAIL.position}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="是否注册安全工程师">
|
||||||
|
<Tag color={MOCK_PERSONNEL_DETAIL.isRegisterEngineer === "是" ? "success" : "error"}>
|
||||||
|
{MOCK_PERSONNEL_DETAIL.isRegisterEngineer}
|
||||||
|
</Tag>
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="出版学术专著、专利、获奖、发表学术论文等" span={2}>{MOCK_PERSONNEL_DETAIL.publications}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="自我申报的专业能力及认定方式" span={2}>{MOCK_PERSONNEL_DETAIL.selfDeclaration}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="主要学习工作经历" span={2}>{MOCK_PERSONNEL_DETAIL.workExperience}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="申报专业能力证明材料" span={2}>
|
||||||
|
<Space><Button type="link" size="small">查看附件</Button><Tag color="success">专业能力证明.pdf</Tag></Space>
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
|
||||||
|
<h4 style={{ fontSize: "0.85rem", color: "#1890ff", margin: "1.25rem 0 0.6rem", paddingBottom: "0.3rem", borderBottom: "2px solid #e6f7ff" }}>证照信息</h4>
|
||||||
|
<Table size="small" bordered rowKey="id" pagination={false} dataSource={MOCK_CERTIFICATES} scroll={{ x: 920 }}
|
||||||
|
columns={[
|
||||||
|
{ title: "证照名称", dataIndex: "name", ellipsis: true },
|
||||||
|
{ title: "证书编号", dataIndex: "certNo", width: 120 },
|
||||||
|
{ title: "证书类别", dataIndex: "category", width: 120 },
|
||||||
|
{ title: "发证机关", dataIndex: "issuer", width: 150, ellipsis: true },
|
||||||
|
{ title: "有效开始日期", dataIndex: "startDate", width: 120 },
|
||||||
|
{ title: "有效结束日期", dataIndex: "endDate", width: 120 },
|
||||||
|
{ title: "操作", fixed: "right", width: 80, render: () => <Button type="link" size="small">查看证书</Button> },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
|
{/* 设备详细信息弹窗 */}
|
||||||
|
<Modal
|
||||||
|
title="设备详细信息"
|
||||||
|
open={equipVisible}
|
||||||
|
onCancel={() => setEquipVisible(false)}
|
||||||
|
width={600}
|
||||||
|
footer={<Button onClick={() => setEquipVisible(false)}>关闭</Button>}
|
||||||
|
>
|
||||||
|
{selectedEquip && (
|
||||||
|
<Descriptions column={1} size="small">
|
||||||
|
<Descriptions.Item label="设备名称">{MOCK_EQUIP_DETAIL.name}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="型号">{MOCK_EQUIP_DETAIL.model}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="仪器分类">{MOCK_EQUIP_DETAIL.category}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="设备类型">{MOCK_EQUIP_DETAIL.type}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="厂家">{MOCK_EQUIP_DETAIL.manufacturer}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="现场校验类型">{MOCK_EQUIP_DETAIL.calibrationType}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="设备流量说明">{MOCK_EQUIP_DETAIL.flowDesc}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="最大流量">{MOCK_EQUIP_DETAIL.maxFlow}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="最小流量">{MOCK_EQUIP_DETAIL.minFlow}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="是否双路">{MOCK_EQUIP_DETAIL.dualChannel}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="校准初始值" span={2}>{MOCK_EQUIP_DETAIL.calibInitValue}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="校准单位" span={2}>{MOCK_EQUIP_DETAIL.calibUnit}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="设备状态">
|
||||||
|
<Tag color={CALIBRATION_MAP[MOCK_EQUIP_DETAIL.status]?.color}>{CALIBRATION_MAP[MOCK_EQUIP_DETAIL.status]?.label}</Tag>
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FilingTabs;
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Button, Form, Select, Space, Table, Tag } from "antd";
|
||||||
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
|
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
||||||
|
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||||
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
|
import { CHANGE_STATUS_MAP } from "~/enumerate/constant";
|
||||||
|
|
||||||
|
const MOCK_DATA = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
orgName: "重庆安评技术研究院有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
filingNo: "BA-2026-001",
|
||||||
|
businessScope: "化工",
|
||||||
|
changeItem: "法定代表人变更",
|
||||||
|
changeStatus: "pending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
orgName: "重庆恒安安全评价有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
filingNo: "BA-2025-032",
|
||||||
|
businessScope: "化工, 建筑施工",
|
||||||
|
changeItem: "注册地址变更",
|
||||||
|
changeStatus: "stuck",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
orgName: "北京中安评价中心(重庆分公司)",
|
||||||
|
orgType: "异地机构",
|
||||||
|
filingNo: "BA-2026-015",
|
||||||
|
businessScope: "矿山",
|
||||||
|
changeItem: "业务范围变更",
|
||||||
|
changeStatus: "approved",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { router } = tools;
|
||||||
|
|
||||||
|
const QualChange = (props) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => setLoading(false), 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = (values) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.setFieldsValue(router.query);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "序号",
|
||||||
|
dataIndex: "id",
|
||||||
|
width: 60,
|
||||||
|
fixed: "left",
|
||||||
|
render: (text, record, index) => index + 1,
|
||||||
|
},
|
||||||
|
{ title: "机构名称", dataIndex: "orgName", width: 220, ellipsis: true },
|
||||||
|
{ title: "机构类型", dataIndex: "orgType", width: 100 },
|
||||||
|
{ title: "备案编号", dataIndex: "filingNo", width: 140, ellipsis: true },
|
||||||
|
{ title: "安全评价业务范围", dataIndex: "businessScope", width: 180, ellipsis: true },
|
||||||
|
{ title: "变更项", dataIndex: "changeItem", width: 140, ellipsis: true },
|
||||||
|
{
|
||||||
|
title: "变更状态",
|
||||||
|
dataIndex: "changeStatus",
|
||||||
|
width: 100,
|
||||||
|
render: (status) => {
|
||||||
|
const config = CHANGE_STATUS_MAP[status];
|
||||||
|
return config ? <Tag color={config.color}>{config.label}</Tag> : status;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
width: 140,
|
||||||
|
fixed: "right",
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space>
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`FilingDetail?id=${record.id}`)}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
{record.changeStatus !== "approved" && (
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`QualReviewForm?id=${record.id}`)}>
|
||||||
|
审核
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageLayout title="备案变更管理">
|
||||||
|
<SearchForm
|
||||||
|
style={{ marginBottom: 24 }}
|
||||||
|
form={form}
|
||||||
|
loading={loading}
|
||||||
|
formLine={[
|
||||||
|
<Form.Item key="orgName" name="orgName">
|
||||||
|
<ControlWrapper.Input label="机构名称" placeholder="请输入" allowClear />
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="filingNo" name="filingNo">
|
||||||
|
<ControlWrapper.Input label="备案编号" placeholder="请输入" allowClear />
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="businessScope" name="businessScope">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="安全评价业务范围"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="石油加工">石油加工</Select.Option>
|
||||||
|
<Select.Option value="化工">化工</Select.Option>
|
||||||
|
<Select.Option value="矿山">矿山</Select.Option>
|
||||||
|
<Select.Option value="建筑施工">建筑施工</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="changeStatus" name="changeStatus">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="变更状态"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="stuck">停滞中</Select.Option>
|
||||||
|
<Select.Option value="pending">待审核</Select.Option>
|
||||||
|
<Select.Option value="approved">已审核</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
]}
|
||||||
|
onReset={handleReset}
|
||||||
|
onFinish={(values) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
rowKey="id"
|
||||||
|
columns={columns}
|
||||||
|
dataSource={MOCK_DATA}
|
||||||
|
scroll={{ y: props.scrollY }}
|
||||||
|
loading={loading}
|
||||||
|
pagination={{
|
||||||
|
total: MOCK_DATA.length,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showTotal: (total) => `共 ${total} 条`,
|
||||||
|
current: router.query.current,
|
||||||
|
pageSize: router.query.pageSize,
|
||||||
|
onChange: (page, pageSize) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
current: page,
|
||||||
|
pageSize,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AntdTableFuncControl(QualChange);
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Button, Form, Select, Space, Table, Tag } from "antd";
|
||||||
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
|
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
||||||
|
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||||
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
|
import { VERIFY_STATUS_MAP } from "~/enumerate/constant";
|
||||||
|
|
||||||
|
const MOCK_DATA = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
orgName: "重庆恒安安全评价有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2025-032",
|
||||||
|
businessScope: "化工, 建筑施工",
|
||||||
|
confirmStatus: "pending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
orgName: "重庆安环检测技术有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2025-028",
|
||||||
|
businessScope: "矿山",
|
||||||
|
confirmStatus: "passed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
orgName: "上海安信评价中心(重庆办)",
|
||||||
|
orgType: "异地机构",
|
||||||
|
certNo: "API-2025-045",
|
||||||
|
businessScope: "石油加工",
|
||||||
|
confirmStatus: "rejected",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { router } = tools;
|
||||||
|
|
||||||
|
const QualConfirm = (props) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => setLoading(false), 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = (values) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.setFieldsValue(router.query);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "序号",
|
||||||
|
dataIndex: "id",
|
||||||
|
width: 60,
|
||||||
|
fixed: "left",
|
||||||
|
render: (text, record, index) => index + 1,
|
||||||
|
},
|
||||||
|
{ title: "机构名称", dataIndex: "orgName", width: 220, ellipsis: true },
|
||||||
|
{ title: "机构类型", dataIndex: "orgType", width: 100 },
|
||||||
|
{ title: "证书编号", dataIndex: "certNo", width: 140, ellipsis: true },
|
||||||
|
{ title: "安全评价业务范围", dataIndex: "businessScope", width: 180, ellipsis: true },
|
||||||
|
{
|
||||||
|
title: "确认状态",
|
||||||
|
dataIndex: "confirmStatus",
|
||||||
|
width: 100,
|
||||||
|
render: (status) => {
|
||||||
|
const config = VERIFY_STATUS_MAP[status];
|
||||||
|
return config ? <Tag color={config.color}>{config.label}</Tag> : status;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
width: 140,
|
||||||
|
fixed: "right",
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space>
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`FilingDetail?id=${record.id}`)}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
{record.confirmStatus !== "passed" && (
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`QualConfirmForm?id=${record.id}`)}>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageLayout title="资质备案确认">
|
||||||
|
<SearchForm
|
||||||
|
style={{ marginBottom: 24 }}
|
||||||
|
form={form}
|
||||||
|
loading={loading}
|
||||||
|
formLine={[
|
||||||
|
<Form.Item key="orgName" name="orgName">
|
||||||
|
<ControlWrapper.Input label="机构名称" placeholder="请输入" allowClear />
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="orgType" name="orgType">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="机构类型"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="本地机构">本地机构</Select.Option>
|
||||||
|
<Select.Option value="异地机构">异地机构</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="businessScope" name="businessScope">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="安全评价业务范围"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="石油加工">石油加工</Select.Option>
|
||||||
|
<Select.Option value="化工">化工</Select.Option>
|
||||||
|
<Select.Option value="矿山">矿山</Select.Option>
|
||||||
|
<Select.Option value="建筑施工">建筑施工</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="confirmStatus" name="confirmStatus">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="确认状态"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="pending">待确认</Select.Option>
|
||||||
|
<Select.Option value="passed">确认通过</Select.Option>
|
||||||
|
<Select.Option value="rejected">打回</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
]}
|
||||||
|
onReset={handleReset}
|
||||||
|
onFinish={(values) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
rowKey="id"
|
||||||
|
columns={columns}
|
||||||
|
dataSource={MOCK_DATA}
|
||||||
|
scroll={{ y: props.scrollY }}
|
||||||
|
loading={loading}
|
||||||
|
pagination={{
|
||||||
|
total: MOCK_DATA.length,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showTotal: (total) => `共 ${total} 条`,
|
||||||
|
current: router.query.current,
|
||||||
|
pageSize: router.query.pageSize,
|
||||||
|
onChange: (page, pageSize) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
current: page,
|
||||||
|
pageSize,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AntdTableFuncControl(QualConfirm);
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
.qual-confirm-form {
|
||||||
|
.summary-card {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card-title {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-label {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-value {
|
||||||
|
font-size: 0.88rem;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 0.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-card {
|
||||||
|
background: #f8fafc;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-item {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-number {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0.15rem 0;
|
||||||
|
|
||||||
|
&.green {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-warning {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
padding: 0.4rem 0.6rem;
|
||||||
|
background: #fffbeb;
|
||||||
|
border: 1px solid #fde68a;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.opinion-card {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opinion-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opinion-label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 0.75rem;
|
||||||
|
border-top: 1px solid #d9d9d9;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { Button, Select, Tag, Space, Input } from "antd";
|
||||||
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
|
import { MOCK_DETAIL, MOCK_MATERIALS, MOCK_PERSONNEL } from "../mockData";
|
||||||
|
import "./indes.less";
|
||||||
|
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
const LIST_PATH = "./../";
|
||||||
|
|
||||||
|
const QualConfirmForm = (props) => {
|
||||||
|
const [result, setResult] = useState(undefined);
|
||||||
|
const [opinion, setOpinion] = useState("");
|
||||||
|
const detail = MOCK_DETAIL;
|
||||||
|
|
||||||
|
const totalCount = MOCK_MATERIALS.length;
|
||||||
|
const qualifiedCount = 8; // mock 符合数
|
||||||
|
const isPersonnelMet = MOCK_PERSONNEL.length >= 25;
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
console.log("确认提交:", { result, opinion });
|
||||||
|
// TODO: 调用接口
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageLayout
|
||||||
|
title={
|
||||||
|
<Space>
|
||||||
|
<span>资质备案确认</span>
|
||||||
|
<Tag color="warning">待确认</Tag>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
history={props.history}
|
||||||
|
previous
|
||||||
|
>
|
||||||
|
<div className="qual-confirm-form">
|
||||||
|
{/* 基本信息 */}
|
||||||
|
<div className="summary-card">
|
||||||
|
<div className="summary-card-title">基本信息</div>
|
||||||
|
<div className="summary-card-grid">
|
||||||
|
<div>
|
||||||
|
<div className="summary-label">机构名称</div>
|
||||||
|
<div className="summary-value">{detail.orgName}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="summary-label">证书编号</div>
|
||||||
|
<div className="summary-value">{detail.certNo}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="summary-label">业务范围</div>
|
||||||
|
<div className="summary-value">{detail.scopeName}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="summary-label">提交时间</div>
|
||||||
|
<div className="summary-value">2026-06-20</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 分析结果 */}
|
||||||
|
<div className="analysis-card">
|
||||||
|
<div className="summary-card-title">分析结果</div>
|
||||||
|
<div className="analysis-grid">
|
||||||
|
<div className="analysis-item">
|
||||||
|
<div className="summary-label">备案材料核验</div>
|
||||||
|
<div className="analysis-number green">{totalCount}/{totalCount}</div>
|
||||||
|
<div className="summary-label">全部已上传</div>
|
||||||
|
</div>
|
||||||
|
<div className="analysis-item">
|
||||||
|
<div className="summary-label">材料符合性</div>
|
||||||
|
<div className="analysis-number green">{qualifiedCount}/{totalCount}</div>
|
||||||
|
<div className="summary-label">符合要求</div>
|
||||||
|
</div>
|
||||||
|
<div className="analysis-item">
|
||||||
|
<div className="summary-label">人员配备</div>
|
||||||
|
<div className="analysis-number" style={{ color: isPersonnelMet ? "#52c41a" : "#faad14" }}>
|
||||||
|
{MOCK_PERSONNEL.length}/25
|
||||||
|
</div>
|
||||||
|
<div className="summary-label">{isPersonnelMet ? "满足要求" : "不满足要求"}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{!isPersonnelMet && (
|
||||||
|
<div className="analysis-warning">
|
||||||
|
当前备案人员{MOCK_PERSONNEL.length}人,需满足专职技术人员不少于25人的要求,建议机构补充人员后再确认。
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{/* 确认意见 */}
|
||||||
|
<div className="opinion-card">
|
||||||
|
<div className="summary-card-title">确认意见</div>
|
||||||
|
<div className="opinion-grid">
|
||||||
|
<div>
|
||||||
|
<div className="opinion-label">确认结果</div>
|
||||||
|
<Select
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
placeholder="请选择"
|
||||||
|
value={result}
|
||||||
|
onChange={setResult}
|
||||||
|
>
|
||||||
|
<Select.Option value="passed">确认通过</Select.Option>
|
||||||
|
<Select.Option value="rejected">打回</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="opinion-label">确认意见</div>
|
||||||
|
<TextArea
|
||||||
|
rows={4}
|
||||||
|
placeholder="请输入确认意见..."
|
||||||
|
value={opinion}
|
||||||
|
onChange={(e) => setOpinion(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 操作按钮 */}
|
||||||
|
<div className="footer-bar">
|
||||||
|
<Button onClick={() => props.history?.push(LIST_PATH)}>取消</Button>
|
||||||
|
<Button type="primary" onClick={handleSubmit}>提交确认</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QualConfirmForm;
|
||||||
|
|
@ -0,0 +1,292 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Button, Form, Select, Space, Table, Tag, Modal, Input, DatePicker } from "antd";
|
||||||
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
|
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
||||||
|
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||||
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
|
import { PUBLICITY_STATUS_MAP } from "~/enumerate/constant";
|
||||||
|
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
const MOCK_DATA = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
orgName: "重庆安评技术研究院有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2026-001",
|
||||||
|
businessScope: "化工, 石油加工",
|
||||||
|
reviewDept: "市应急管理局",
|
||||||
|
reviewTime: "2026-06-20",
|
||||||
|
status: "pending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
orgName: "重庆恒安安全评价有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2025-032",
|
||||||
|
businessScope: "化工",
|
||||||
|
reviewDept: "市应急管理局",
|
||||||
|
reviewTime: "2026-05-15",
|
||||||
|
status: "published",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
orgName: "北京中安评价中心(重庆分公司)",
|
||||||
|
orgType: "异地机构",
|
||||||
|
certNo: "API-2026-015",
|
||||||
|
businessScope: "矿山, 建筑施工",
|
||||||
|
reviewDept: "市应急管理局",
|
||||||
|
reviewTime: "2026-06-18",
|
||||||
|
status: "pending",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { router } = tools;
|
||||||
|
|
||||||
|
const QualPublicity = (props) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [publicityVisible, setPublicityVisible] = useState(false);
|
||||||
|
const [publicityTarget, setPublicityTarget] = useState(null);
|
||||||
|
const [publicityDept, setPublicityDept] = useState(undefined);
|
||||||
|
const [publicityContent, setPublicityContent] = useState("");
|
||||||
|
const [publicityStartDate, setPublicityStartDate] = useState(null);
|
||||||
|
const [publicityEndDate, setPublicityEndDate] = useState(null);
|
||||||
|
|
||||||
|
const openPublicity = (record) => {
|
||||||
|
setPublicityTarget(record);
|
||||||
|
setPublicityDept(undefined);
|
||||||
|
setPublicityContent(
|
||||||
|
"依据《安全评价机构管理规定》等相关法规,经审核,该机构符合安全评价机构资质条件,现予以公示,接受社会监督。"
|
||||||
|
);
|
||||||
|
setPublicityStartDate(null);
|
||||||
|
setPublicityEndDate(null);
|
||||||
|
setPublicityVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePublicitySubmit = () => {
|
||||||
|
console.log("公示提交:", {
|
||||||
|
target: publicityTarget,
|
||||||
|
dept: publicityDept,
|
||||||
|
content: publicityContent,
|
||||||
|
startDate: publicityStartDate,
|
||||||
|
endDate: publicityEndDate,
|
||||||
|
});
|
||||||
|
setPublicityVisible(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => setLoading(false), 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = (values) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.setFieldsValue(router.query);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "序号",
|
||||||
|
dataIndex: "id",
|
||||||
|
width: 60,
|
||||||
|
fixed: "left",
|
||||||
|
render: (text, record, index) => index + 1,
|
||||||
|
},
|
||||||
|
{ title: "机构名称", dataIndex: "orgName", width: 220, ellipsis: true },
|
||||||
|
{ title: "机构类型", dataIndex: "orgType", width: 100 },
|
||||||
|
{ title: "证书编号", dataIndex: "certNo", width: 140, ellipsis: true },
|
||||||
|
{ title: "安全评价业务范围", dataIndex: "businessScope", width: 180, ellipsis: true },
|
||||||
|
{ title: "审核部门", dataIndex: "reviewDept", width: 120, ellipsis: true },
|
||||||
|
{ title: "审核通过时间", dataIndex: "reviewTime", width: 120 },
|
||||||
|
{
|
||||||
|
title: "公示状态",
|
||||||
|
dataIndex: "status",
|
||||||
|
width: 100,
|
||||||
|
render: (status) => {
|
||||||
|
const config = PUBLICITY_STATUS_MAP[status];
|
||||||
|
return config ? <Tag color={config.color}>{config.label}</Tag> : status;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
width: 180,
|
||||||
|
fixed: "right",
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space>
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`FilingDetail?id=${record.id}`)}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
{record.status === "pending" && (
|
||||||
|
<Button type="link" size="small" onClick={() => openPublicity(record)}>
|
||||||
|
公示
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button type="link" size="small">
|
||||||
|
公示信息
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageLayout title="备案公示管理">
|
||||||
|
<SearchForm
|
||||||
|
style={{ marginBottom: 24 }}
|
||||||
|
form={form}
|
||||||
|
loading={loading}
|
||||||
|
formLine={[
|
||||||
|
<Form.Item key="orgName" name="orgName">
|
||||||
|
<ControlWrapper.Input label="机构名称" placeholder="请输入" allowClear />
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="orgType" name="orgType">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="机构类型"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="本地机构">本地机构</Select.Option>
|
||||||
|
<Select.Option value="异地机构">异地机构</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="businessScope" name="businessScope">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="安全评价业务范围"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="石油加工">石油加工</Select.Option>
|
||||||
|
<Select.Option value="化工">化工</Select.Option>
|
||||||
|
<Select.Option value="矿山">矿山</Select.Option>
|
||||||
|
<Select.Option value="建筑施工">建筑施工</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="status" name="status">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="公示状态"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="pending">待公示</Select.Option>
|
||||||
|
<Select.Option value="published">已公示</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
]}
|
||||||
|
onReset={handleReset}
|
||||||
|
onFinish={(values) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
rowKey="id"
|
||||||
|
columns={columns}
|
||||||
|
dataSource={MOCK_DATA}
|
||||||
|
scroll={{ y: props.scrollY }}
|
||||||
|
loading={loading}
|
||||||
|
pagination={{
|
||||||
|
total: MOCK_DATA.length,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showTotal: (total) => `共 ${total} 条`,
|
||||||
|
current: router.query.current,
|
||||||
|
pageSize: router.query.pageSize,
|
||||||
|
onChange: (page, pageSize) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
current: page,
|
||||||
|
pageSize,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
title="备案公示"
|
||||||
|
open={publicityVisible}
|
||||||
|
onCancel={() => setPublicityVisible(false)}
|
||||||
|
width={560}
|
||||||
|
footer={
|
||||||
|
<div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}>
|
||||||
|
<Button onClick={() => setPublicityVisible(false)}>取消</Button>
|
||||||
|
<Button type="primary" onClick={handlePublicitySubmit}>提交公示</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div style={{ display: "grid", gap: "0.8rem" }}>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>公示信息</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>机构名称</div>
|
||||||
|
<div style={{ fontSize: "0.88rem", fontWeight: 500 }}>{publicityTarget?.orgName || "—"}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>公示部门</div>
|
||||||
|
<Select
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
placeholder="请选择"
|
||||||
|
value={publicityDept}
|
||||||
|
onChange={setPublicityDept}
|
||||||
|
>
|
||||||
|
<Select.Option value="city">市应急管理局</Select.Option>
|
||||||
|
<Select.Option value="district">县区应急管理局</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>公示内容</div>
|
||||||
|
<TextArea
|
||||||
|
rows={4}
|
||||||
|
placeholder="请输入公示内容..."
|
||||||
|
value={publicityContent}
|
||||||
|
onChange={(e) => setPublicityContent(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.5rem" }}>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>公示开始时间</div>
|
||||||
|
<DatePicker
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
placeholder="请选择"
|
||||||
|
value={publicityStartDate}
|
||||||
|
onChange={setPublicityStartDate}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>公示结束时间</div>
|
||||||
|
<DatePicker
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
placeholder="请选择"
|
||||||
|
value={publicityEndDate}
|
||||||
|
onChange={setPublicityEndDate}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AntdTableFuncControl(QualPublicity);
|
||||||
|
|
@ -0,0 +1,212 @@
|
||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { Button, Form, Select, Space, Table, Tag } from "antd";
|
||||||
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
|
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
||||||
|
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||||
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
||||||
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
||||||
|
import { REVIEW_STATUS_MAP, EXPERT_STATUS_MAP } from "~/enumerate/constant";
|
||||||
|
|
||||||
|
// 静态模拟数据
|
||||||
|
const MOCK_DATA = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
orgName: "重庆安评技术研究院有限公司",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2026-001",
|
||||||
|
businessScope: "化工, 石油加工",
|
||||||
|
expertStatus: "pending",
|
||||||
|
reviewStatus: "pending",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
orgName: "北京中安评价中心(重庆分公司)",
|
||||||
|
orgType: "异地机构",
|
||||||
|
certNo: "API-2026-015",
|
||||||
|
businessScope: "矿山, 建筑施工",
|
||||||
|
expertStatus: "arranging",
|
||||||
|
reviewStatus: "reviewing",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
orgName: "重庆渝安风险评估中心",
|
||||||
|
orgType: "本地机构",
|
||||||
|
certNo: "API-2026-008",
|
||||||
|
businessScope: "化工",
|
||||||
|
expertStatus: "none",
|
||||||
|
reviewStatus: "rejected",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { router } = tools;
|
||||||
|
|
||||||
|
const QualReview = (props) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
setLoading(true);
|
||||||
|
setTimeout(() => setLoading(false), 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = (values) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.setFieldsValue(router.query);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: "序号",
|
||||||
|
dataIndex: "id",
|
||||||
|
width: 60,
|
||||||
|
fixed: "left",
|
||||||
|
render: (text, record, index) => index + 1,
|
||||||
|
},
|
||||||
|
{ title: "机构名称", dataIndex: "orgName", width: 220, ellipsis: true },
|
||||||
|
{ title: "机构类型", dataIndex: "orgType", width: 100 },
|
||||||
|
{ title: "证书编号", dataIndex: "certNo", width: 140, ellipsis: true },
|
||||||
|
{ title: "安全评价业务范围", dataIndex: "businessScope", width: 180, ellipsis: true },
|
||||||
|
{
|
||||||
|
title: "专家核验",
|
||||||
|
dataIndex: "expertStatus",
|
||||||
|
width: 100,
|
||||||
|
render: (status) => {
|
||||||
|
const config = EXPERT_STATUS_MAP[status];
|
||||||
|
return config ? <Tag color={config.color}>{config.label}</Tag> : '--';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "审核状态",
|
||||||
|
dataIndex: "reviewStatus",
|
||||||
|
width: 100,
|
||||||
|
render: (status) => {
|
||||||
|
const config = REVIEW_STATUS_MAP[status];
|
||||||
|
return config ? <Tag color={config.color}>{config.label}</Tag> : '--';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
width: 140,
|
||||||
|
fixed: "right",
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space>
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`FilingDetail?id=${record.id}`)}>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
{record.reviewStatus === "pending" && (
|
||||||
|
<Button type="link" size="small" onClick={() => props.history.push(`QualReviewForm?id=${record.id}`)}>
|
||||||
|
审核
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageLayout title="资质备案审核">
|
||||||
|
<SearchForm
|
||||||
|
style={{ marginBottom: 24 }}
|
||||||
|
form={form}
|
||||||
|
loading={loading}
|
||||||
|
formLine={[
|
||||||
|
<Form.Item key="orgName" name="orgName">
|
||||||
|
<ControlWrapper.Input label="机构名称" placeholder="请输入" allowClear />
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="orgType" name="orgType">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="机构类型"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="本地机构">本地机构</Select.Option>
|
||||||
|
<Select.Option value="异地机构">异地机构</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="businessScope" name="businessScope">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="安全评价业务范围"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="石油加工">石油加工</Select.Option>
|
||||||
|
<Select.Option value="化工">化工</Select.Option>
|
||||||
|
<Select.Option value="矿山">矿山</Select.Option>
|
||||||
|
<Select.Option value="建筑施工">建筑施工</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="needExpertCheck" name="needExpertCheck">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="是否专家核验"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="yes">是</Select.Option>
|
||||||
|
<Select.Option value="no">否</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
<Form.Item key="reviewStatus" name="reviewStatus">
|
||||||
|
<ControlWrapper.Select
|
||||||
|
label="审核状态"
|
||||||
|
placeholder="请选择"
|
||||||
|
allowClear
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
<Select.Option value="pending">待审核</Select.Option>
|
||||||
|
<Select.Option value="reviewing">审核中</Select.Option>
|
||||||
|
<Select.Option value="rejected">打回</Select.Option>
|
||||||
|
</ControlWrapper.Select>
|
||||||
|
</Form.Item>,
|
||||||
|
]}
|
||||||
|
onReset={handleReset}
|
||||||
|
onFinish={(values) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
...values,
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
rowKey="id"
|
||||||
|
columns={columns}
|
||||||
|
dataSource={MOCK_DATA}
|
||||||
|
scroll={{ y: props.scrollY }}
|
||||||
|
loading={loading}
|
||||||
|
pagination={{
|
||||||
|
total: MOCK_DATA.length,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showTotal: (total) => `共 ${total} 条`,
|
||||||
|
current: router.query.current,
|
||||||
|
pageSize: router.query.pageSize,
|
||||||
|
onChange: (page, pageSize) => {
|
||||||
|
router.query = {
|
||||||
|
...router.query,
|
||||||
|
current: page,
|
||||||
|
pageSize,
|
||||||
|
};
|
||||||
|
handleSearch();
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AntdTableFuncControl(QualReview);
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
.qual-review-form {
|
||||||
|
// 法律规定内容
|
||||||
|
.legal-check-bar {
|
||||||
|
background: #f8fafc;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.6rem 0.75rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-check-title {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-check-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-check-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.4rem;
|
||||||
|
padding: 0.3rem 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-check-item-desc {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部操作栏
|
||||||
|
.footer-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 0.75rem;
|
||||||
|
border-top: 1px solid #d9d9d9;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { Button, Tag, Space, Modal, Select, Input } from "antd";
|
||||||
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||||
|
import { REVIEW_STATUS_MAP } from "~/enumerate/constant";
|
||||||
|
import { MOCK_DETAIL, MOCK_MATERIALS, LEGAL_CHECK_ITEMS, LEGAL_STATUS_STYLE } from "../mockData";
|
||||||
|
import FilingTabs from "../FilingTabs";
|
||||||
|
import "./indes.less";
|
||||||
|
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
const QualReviewForm = (props) => {
|
||||||
|
const [compliance, setCompliance] = useState({});
|
||||||
|
const [reviewVisible, setReviewVisible] = useState(false);
|
||||||
|
const [reviewResult, setReviewResult] = useState(undefined);
|
||||||
|
const [expert, setExpert] = useState(undefined);
|
||||||
|
const [remark, setRemark] = useState("");
|
||||||
|
const detail = MOCK_DETAIL;
|
||||||
|
const statusConfig = REVIEW_STATUS_MAP[detail.reviewStatus];
|
||||||
|
|
||||||
|
const passCount = Object.values(compliance).filter((v) => v === "pass").length;
|
||||||
|
const failCount = Object.values(compliance).filter((v) => v === "fail").length;
|
||||||
|
const evaluatedCount = passCount + failCount;
|
||||||
|
const unmetCount = MOCK_MATERIALS.length - evaluatedCount;
|
||||||
|
|
||||||
|
const handleSubmit = (action) => {
|
||||||
|
console.log("审核提交:", { action, reviewResult, expert, remark, compliance });
|
||||||
|
setReviewVisible(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageLayout
|
||||||
|
title={
|
||||||
|
<Space>
|
||||||
|
<span>资质备案审核</span>
|
||||||
|
{statusConfig && <Tag color={statusConfig.color}>{statusConfig.label}</Tag>}
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
history={props.history}
|
||||||
|
previous
|
||||||
|
footer={<Button type="primary" onClick={() => setReviewVisible(true)}>审核操作</Button>}
|
||||||
|
>
|
||||||
|
<div className="qual-review-form">
|
||||||
|
<div className="legal-check-bar">
|
||||||
|
<div className="legal-check-title">法律规定内容</div>
|
||||||
|
<div className="legal-check-grid">
|
||||||
|
{LEGAL_CHECK_ITEMS.map((item) => {
|
||||||
|
const style = LEGAL_STATUS_STYLE[item.status];
|
||||||
|
return (
|
||||||
|
<div key={item.key} className="legal-check-item" style={{ borderLeft: `3px solid ${style.borderColor}`, background: style.bg }}>
|
||||||
|
<span>{style.icon}</span>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontWeight: 500 }}>{item.title}</div>
|
||||||
|
<div className="legal-check-item-desc">{item.desc}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FilingTabs
|
||||||
|
detail={detail}
|
||||||
|
isReview
|
||||||
|
compliance={compliance}
|
||||||
|
onComplianceChange={(id, v) => setCompliance((prev) => ({ ...prev, [id]: v }))}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
title="审核操作"
|
||||||
|
open={reviewVisible}
|
||||||
|
onCancel={() => setReviewVisible(false)}
|
||||||
|
width={580}
|
||||||
|
footer={
|
||||||
|
<div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}>
|
||||||
|
<Button onClick={() => setReviewVisible(false)}>取消</Button>
|
||||||
|
<Button type="primary" onClick={() => handleSubmit("submit")}>提交</Button>
|
||||||
|
<Button type="primary" style={{ background: "#52c41a", borderColor: "#52c41a" }} onClick={() => handleSubmit("pass")}>通过</Button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div style={{ background: "#f8fafc", border: "1px solid #d9d9d9", borderRadius: 6, padding: "0.75rem", marginBottom: "1rem" }}>
|
||||||
|
<div style={{ fontSize: "0.88rem", fontWeight: 600, marginBottom: "0.5rem" }}>评价分析</div>
|
||||||
|
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr 1fr", gap: "0.4rem" }}>
|
||||||
|
<div style={statStyle}><div style={statLabelStyle}>已核验材料</div><div style={{ fontSize: "1.1rem", fontWeight: 700, color: "#1677ff" }}>{evaluatedCount}</div></div>
|
||||||
|
<div style={statStyle}><div style={statLabelStyle}>符合</div><div style={{ fontSize: "1.1rem", fontWeight: 700, color: "#52c41a" }}>{passCount}</div></div>
|
||||||
|
<div style={statStyle}><div style={statLabelStyle}>不符合</div><div style={{ fontSize: "1.1rem", fontWeight: 700, color: "#ff4d4f" }}>{failCount}</div></div>
|
||||||
|
<div style={statStyle}><div style={statLabelStyle}>条件未满足</div><div style={{ fontSize: "1.1rem", fontWeight: 700, color: "#faad14" }}>{unmetCount}</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: "grid", gap: "0.6rem" }}>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>审核结果</div>
|
||||||
|
<Select style={{ width: "100%" }} placeholder="请选择" value={reviewResult} onChange={setReviewResult}>
|
||||||
|
<Select.Option value="pass">通过</Select.Option>
|
||||||
|
<Select.Option value="pending">待定</Select.Option>
|
||||||
|
<Select.Option value="reject">不通过</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>指派专家</div>
|
||||||
|
<Select style={{ width: "100%" }} placeholder="— 请选择 —" value={expert} onChange={setExpert}>
|
||||||
|
<Select.Option value="chen">陈教授(化工安全)</Select.Option>
|
||||||
|
<Select.Option value="li">李教授(矿山安全)</Select.Option>
|
||||||
|
<Select.Option value="wang">王高工(建筑施工)</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{ fontSize: "0.8rem", marginBottom: 4 }}>综合审核意见</div>
|
||||||
|
<TextArea rows={3} placeholder="请输入综合审核意见..." value={remark} onChange={(e) => setRemark(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const statStyle = { background: "#fff", border: "1px solid #d9d9d9", borderRadius: 6, padding: "0.4rem", textAlign: "center" };
|
||||||
|
const statLabelStyle = { fontSize: "0.7rem", color: "rgba(0,0,0,0.45)" };
|
||||||
|
|
||||||
|
export default QualReviewForm;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default (props)=>{
|
||||||
|
return (
|
||||||
|
<div style={{height: "100%"}}>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
// 资质备案审核相关 mock 数据,FilingDetail 和 QualReviewForm 共享
|
||||||
|
|
||||||
|
export const MOCK_DETAIL = {
|
||||||
|
id: 1,
|
||||||
|
scopeName: "化工、石油加工",
|
||||||
|
filingRegion: "重庆市渝北区",
|
||||||
|
orgName: "重庆安评技术研究院有限公司",
|
||||||
|
orgType: "本地单位",
|
||||||
|
creditCode: "915001072028699512",
|
||||||
|
officeAddress: "重庆市沙坪坝区大学城东路20号重庆科技学院第39栋西南角实习用房三楼",
|
||||||
|
registerAddress: "同上",
|
||||||
|
certNo: "API-2026-001",
|
||||||
|
website: "www.cqap.com",
|
||||||
|
legalPerson: "郑远平",
|
||||||
|
legalPhone: "023-68705577",
|
||||||
|
contactPerson: "陈芳",
|
||||||
|
contactPhone: "139****9012",
|
||||||
|
fixedAssets: "1200",
|
||||||
|
officeArea: "1200 ㎡",
|
||||||
|
archiveArea: "80 ㎡",
|
||||||
|
evaluatorCount: "25 人",
|
||||||
|
registerEngineerCount: "12 人",
|
||||||
|
description: "重庆安评技术研究院成立于2015年,是一家专业从事安全评价、安全咨询、安全技术开发与转让的综合性安全技术服务机构。",
|
||||||
|
reviewStatus: "pending",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MOCK_MATERIALS = [
|
||||||
|
{ id: 1, name: "申请材料目录(原件)", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 2, name: "申请书(原件)", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 3, name: "法人证明(复印件)", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 4, name: "三年内无重大违法失信记录查询证明", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 5, name: "法定代表人承诺书(原件)", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 6, name: "固定资产法定证明材料", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 7, name: "工作场所及档案室面积证明", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 8, name: "安全评价师专业能力证明", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 9, name: "相关负责人证明材料", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
{ id: 10, name: "机构内部管理制度", attachment: "纸质版扫描件", format: "pdf", status: "uploaded" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const MOCK_PERSONNEL = [
|
||||||
|
{ id: 1, name: "张建国", type: "评价师", position: "高级评价师", title: "高级工程师", ability: "化工工艺安全风险评估" },
|
||||||
|
{ id: 2, name: "李明华", type: "评价师", position: "评价师", title: "工程师", ability: "矿山安全评价" },
|
||||||
|
{ id: 3, name: "王丽萍", type: "管理人员", position: "人事主管", title: "—", ability: "人力资源管理" },
|
||||||
|
{ id: 4, name: "陈志强", type: "评价师", position: "评价师", title: "工程师", ability: "建筑施工安全评估" },
|
||||||
|
{ id: 5, name: "赵磊", type: "管理人员", position: "综合部主任", title: "—", ability: "安全管理体系" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const MOCK_EQUIPMENT = [
|
||||||
|
{ id: 1, name: "气相色谱仪", model: "GC-2018", manufacturer: "岛津", calibration: "done" },
|
||||||
|
{ id: 2, name: "噪声计", model: "HS-6288", manufacturer: "杭州爱华", calibration: "done" },
|
||||||
|
{ id: 3, name: "粉尘采样器", model: "FC-5A", manufacturer: "北京劳保所", calibration: "pending" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const MOCK_EQUIP_DETAIL = {
|
||||||
|
name: "气相色谱仪",
|
||||||
|
model: "GC-2018",
|
||||||
|
category: "分析仪器",
|
||||||
|
type: "色谱检测类",
|
||||||
|
manufacturer: "岛津",
|
||||||
|
calibrationType: "定期检定",
|
||||||
|
flowDesc: "载气流量 30mL/min",
|
||||||
|
maxFlow: "100 mL/min",
|
||||||
|
minFlow: "1 mL/min",
|
||||||
|
dualChannel: "否",
|
||||||
|
calibInitValue: "0.0001 mg/m³",
|
||||||
|
calibUnit: "重庆市计量质量检测研究院",
|
||||||
|
status: "done",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MOCK_PERSONNEL_DETAIL = {
|
||||||
|
name: "张建国",
|
||||||
|
gender: "男",
|
||||||
|
qualScope: "化工",
|
||||||
|
birthDate: "1985-03-15",
|
||||||
|
officeAddress: "重庆市渝北区龙山街道100号",
|
||||||
|
major: "安全工程",
|
||||||
|
certLevel: "安全评价师一级 / SJP-2020-****",
|
||||||
|
email: "zhangjg@cqap.com",
|
||||||
|
personnelType: "专职评价师",
|
||||||
|
idCard: "500***********1234",
|
||||||
|
currentAddress: "重庆市渝北区新牌坊某路某号",
|
||||||
|
education: "全日制 · 本科",
|
||||||
|
graduateSchool: "重庆大学",
|
||||||
|
position: "高级评价师",
|
||||||
|
isRegisterEngineer: "是",
|
||||||
|
publications: "发表安全评价相关论文3篇,参与编制行业标准1项",
|
||||||
|
selfDeclaration: "化工工艺安全风险评估,通过注册安全工程师资格考试认定",
|
||||||
|
workExperience: "2008-2012 重庆大学 安全工程专业 本科;2012-至今 重庆安评技术研究院有限公司 评价师",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MOCK_CERTIFICATES = [
|
||||||
|
{ id: 1, name: "危险化学品经营许可证", certNo: "AQSC001", category: "安全生产证书", issuer: "重庆市应急管理局", startDate: "2025-03-29", endDate: "2028-03-28" },
|
||||||
|
{ id: 2, name: "安全评价机构资质证书", certNo: "API-2026-001", category: "甲级资质", issuer: "重庆市应急管理局", startDate: "2026-01-15", endDate: "2029-01-14" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const CALIBRATION_MAP = {
|
||||||
|
done: { label: "已检定", color: "success" },
|
||||||
|
pending: { label: "待检定", color: "warning" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LEGAL_CHECK_ITEMS = [
|
||||||
|
{ key: "qualification", title: "主体资格", desc: "独立法人资格,固定资产不少于一千万元", status: "pass" },
|
||||||
|
{ key: "facility", title: "场所与设备", desc: "工作场所建筑面积不少于1000㎡", status: "pass" },
|
||||||
|
{ key: "staffCount", title: "人员数量与结构", desc: "专职技术人员≥25人,中级注安师≥30%", status: "pass" },
|
||||||
|
{ key: "staffExp", title: "人员资历", desc: "专职技术人员在本行业领域工作二年以上", status: "pass" },
|
||||||
|
{ key: "keyRole", title: "关键岗位要求", desc: "负责人具有高级职称,工作八年以上", status: "pass" },
|
||||||
|
{ key: "management", title: "管理体系", desc: "需核验文件化管理体系是否符合要求", status: "warn" },
|
||||||
|
{ key: "commitment", title: "责任承诺", desc: "法定代表人已出具承诺书", status: "pass" },
|
||||||
|
{ key: "disclosure", title: "信息公开", desc: "未检测到公示网站", status: "fail" },
|
||||||
|
{ key: "credit", title: "信用记录", desc: "三年内无重大违法失信记录", status: "pass" },
|
||||||
|
{ key: "other", title: "其他", desc: "法律、行政法规规定的其他条件", status: "pass" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const LEGAL_STATUS_STYLE = {
|
||||||
|
pass: { icon: "✅", borderColor: "#059669", bg: "#f0fdf4" },
|
||||||
|
warn: { icon: "⚠️", borderColor: "#d97706", bg: "#fffbeb" },
|
||||||
|
fail: { icon: "❌", borderColor: "#dc2626", bg: "#fef2f2" },
|
||||||
|
};
|
||||||
|
|
@ -2,6 +2,7 @@ import { ImportCore } from "@cqsjjb/jjb-common-decorator/module";
|
||||||
import { theme as antdTheme, App, ConfigProvider } from "antd";
|
import { theme as antdTheme, App, ConfigProvider } from "antd";
|
||||||
import language from "antd/locale/zh_CN";
|
import language from "antd/locale/zh_CN";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import "./index.less";
|
||||||
|
|
||||||
import { InjectContext } from "~/enumerate/context";
|
import { InjectContext } from "~/enumerate/context";
|
||||||
import SimulatedLayout from "./Layout";
|
import SimulatedLayout from "./Layout";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
.pageLayout-extra{
|
||||||
|
margin: 0px 0px 24px;
|
||||||
|
color: rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
.micro-temp-modal-body{
|
||||||
|
max-height: 630px;
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
}
|
||||||
|
body{
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
.micro-temp-layout-container .micro-temp-lay-container-bottom{
|
||||||
|
padding: 10px 24px !important;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue