证件页面

main
wangyunfei 2 weeks ago
parent c8fe3cfdad
commit 60bcc32a26

@ -0,0 +1,4 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="7.5" width="16" height="2" fill="#3C7DFF"/>
<circle cx="8" cy="8.5" r="3.5" fill="white" stroke="#3C7DFF"/>
</svg>

After

Width:  |  Height:  |  Size: 220 B

@ -1,10 +1,11 @@
import React, { useState } from 'react';
import { Card, Row, Col, Statistic, Progress, Button, Space } from 'antd';
import styles from './basic.less';
import ResponsibilityImplementation from './module/ResponsibilityImplementation'; //责任落实
import OnlineMonitoring from './module/OnlineMonitoring'; //在线监测预警
import RiskAssessment from './module/RiskAssessment'; //风险管控
import EvaluationReport from './module/EvaluationReport'; //评估报告
import ResponsibilityImplementation from './components/ResponsibilityImplementation';
import OnlineMonitoring from './components/OnlineMonitoring';
import RiskAssessment from './components/RiskAssessment';
import EvaluationReport from './components/EvaluationReport';
import LicenseManagement from './components/LicenseManagement';
@ -20,6 +21,8 @@ const SafeMajorHazardList = () => {
switch (activeModule) {
case 'organization':
return <ResponsibilityImplementation />;
case 'license':
return <LicenseManagement />;
case 'equipment':
return <OnlineMonitoring />;
case 'firefighting':
@ -40,11 +43,11 @@ const SafeMajorHazardList = () => {
onClick={() => handleModuleClick("organization")}
>组织机构管理
</Button>
{/* <Button
className={`${styles.TopButtonItem} ${activeModule === "equipment" ? styles.active : ""}`}
onClick={() => handleModuleClick("equipment")}
>设备设施管理
</Button> */}
<Button
className={`${styles.TopButtonItem} ${activeModule === "license" ? styles.active : ""}`}
onClick={() => handleModuleClick("license")}
>资质证照管理
</Button>
<Button
className={`${styles.TopButtonItem} ${activeModule === "firefighting" ? styles.active : ""}`}
onClick={() => handleModuleClick("firefighting")}

@ -244,7 +244,7 @@ const EvaluationReport = () => {
width: 1
},
itemStyle: {
color: '#FFFFFF',
color: '#FFFFF',
borderColor: '#1269FF',
borderWidth: 1
},

@ -0,0 +1,301 @@
import React, { useEffect, useRef } from 'react';
import { Card, Input, Select, Button, Table, Tag, Space, Typography } from 'antd';
import { SearchOutlined, PlusOutlined } from '@ant-design/icons';
import * as echarts from 'echarts';
import styles from './LicenseManagement.less';
import icon_echart from '@/assets/business_basic/icon_echart.svg';
const { Title } = Typography;
const { Search } = Input;
const { Option } = Select;
const LicenseManagement = () => {
const chartRef = useRef(null);
// 图表数据
const chartData = [
{ name: '安全生产许可证', value: 35, itemStyle: { color: '#3C7DFF' } },
{ name: '安全评估报告', value: 25, itemStyle: { color: '#FF8800' } },
{ name: '安全三同时材料', value: 20, itemStyle: { color: '#FF3E48' } },
{ name: '施工资质证书', value: 15, itemStyle: { color: '#FFC403' } },
{ name: '应急预案', value: 10, itemStyle: { color: '#22C55E' } },
{ name: '其他', value: 5, itemStyle: { color: '#31BCFF' } }
];
// 初始化图表
useEffect(() => {
if (chartRef.current) {
const chart = echarts.init(chartRef.current);
const option = {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'horizontal',
bottom: 0,
left: 'center',
itemWidth: 14,
itemHeight: 4,
itemGap: 10,
textStyle: {
fontSize: 12,
color: '#333',
width: 100
},
formatter: function (name) {
return name;
},
data: (() => {
// 找到最长的名称长度
const maxLength = Math.max(...chartData.map(item => item.name.length));
// 将所有名称填充到相同长度
return chartData.map(item => {
const paddingLength = maxLength - item.name.length;
return item.name + ' '.repeat(paddingLength);
});
})()
},
series: [
{
name: '证件类型分布',
type: 'pie',
radius: ['20%', '65%'],
center: ['50%', '38%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 5,
// color:"red",/
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '16',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: (() => {
// 找到最长的名称长度
const maxLength = Math.max(...chartData.map(item => item.name.length));
// 将所有名称填充到相同长度
return chartData.map(item => ({
...item,
name: item.name + ' '.repeat(maxLength - item.name.length)
}));
})()
}
]
};
chart.setOption(option);
// 响应式处理
const handleResize = () => {
chart.resize();
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
chart.dispose();
};
}
}, []);
// 表格数据
const tableData = [
{
key: '1',
no: '01',
name: '安全生产许可证',
type: '资质证书',
id: 'HQ-XF-01-001',
authority: '应急管理部',
validUntil: '2025-09-10',
status: '已过期',
statusType: 'error'
},
{
key: '2',
no: '02',
name: '安全预评估报告',
type: '安全三同时',
id: 'HQ-XF-02-015',
authority: '第三方评估机构',
validUntil: '2025-09-10',
status: '15天后到期',
statusType: 'warning'
},
{
key: '3',
no: '03',
name: '施工资质证书',
type: '资质证书',
id: 'HQ-XF-03-007',
authority: '3设计院',
validUntil: '2025-09-10',
status: '有效',
statusType: 'success'
},
{
key: '4',
no: '04',
name: '安全标准化证书',
type: '资质证书',
id: 'HQ-XF-03-007',
authority: '第三方评估机构',
validUntil: '2025-09-10',
status: '有效',
statusType: 'success'
}
];
// 表格列定义
const columns = [
{
title: '编号',
dataIndex: 'no',
key: 'no',
width: 80,
},
{
title: '证照名称',
dataIndex: 'name',
key: 'name',
width: 150,
},
{
title: '类型',
dataIndex: 'type',
key: 'type',
width: 120,
},
{
title: '编号',
dataIndex: 'id',
key: 'id',
width: 150,
},
{
title: '发证机关',
dataIndex: 'authority',
key: 'authority',
width: 150,
},
{
title: '有效期至',
dataIndex: 'validUntil',
key: 'validUntil',
width: 120,
},
{
title: '状态',
dataIndex: 'status',
key: 'status',
width: 120,
render: (text, record) => (
<Tag color={record.statusType === 'success' ? 'green' :
record.statusType === 'warning' ? 'orange' : 'red'}>
{text}
</Tag>
),
},
{
title: '操作',
key: 'action',
width: 120,
render: () => (
<Space size="small">
<Button type="link" size="small">更新</Button>
<Button type="link" size="small">查看</Button>
</Space>
),
},
];
return (
<div className={styles.licenseManagementContainer}>
<div className={styles.topSectionContainer}>
<div className={styles.firstBlock}>
<div className={styles.chartHeader}>
<div className={styles.colorBlock}></div>
<span className={styles.chartTitle}>证件类型分布</span>
</div>
<div className={styles.chartContainer}>
<div ref={chartRef} className={styles.chart}></div>
</div>
</div>
<div className={styles.secondBlock}>
<div className={styles.chartHeader}>
<div className={styles.colorBlock}></div>
<span className={styles.chartTitle}>证件类型分布</span>
</div>
<div className={styles.chartContainer}>
需求
</div>
</div>
<div className={styles.thirdBlock}>
待开发
</div>
</div>
{/* 证照列表区域 */}
<Card className={styles.listCard}>
<Title level={4} className={styles.listTitle}>证照列表</Title>
<div className={styles.listToolbar}>
<Search
placeholder="搜索证照名称或编号..."
className={styles.searchInput}
prefix={<SearchOutlined />}
/>
<Select
defaultValue="all"
className={styles.typeFilter}
>
<Option value="all">全部类型</Option>
<Option value="qualification">资质证书</Option>
<Option value="safety">安全三同时</Option>
<Option value="emergency">应急预案</Option>
</Select>
<Button type="primary" icon={<PlusOutlined />} className={styles.addButton}>
新增证照
</Button>
</div>
<Table
columns={columns}
dataSource={tableData}
pagination={{
current: 3,
total: 48,
pageSize: 10,
showSizeChanger: false,
showQuickJumper: true,
showTotal: (total) => `${total}`,
}}
className={styles.licenseTable}
/>
</Card>
</div>
);
};
export default LicenseManagement;

@ -0,0 +1,191 @@
.licenseManagementContainer {
height: 100vh;
.topSectionContainer {
padding: 0;
margin: 15px 0px 15px 5px;
height: 35%;
display: flex;
gap: 15px;
align-items: stretch;
.firstBlock {
width: 30%;
background-color: #fff;
display: flex;
flex-direction: column;
padding: 10px 16px;
border-radius: 2px;
.chartHeader {
display: flex;
align-items: center;
margin-bottom: 16px;
.colorBlock {
width: 2px;
height: 18px;
background-color: #2E4CD4;
margin-right: 8px;
border-radius: 1px;
}
.chartTitle {
font-size: 16px;
font-weight: 500;
color: #333333;
line-height: 18px;
}
}
.chartContainer {
flex: 1;
width: 100%;
position: relative;
.chart {
width: 100%;
height: 100%;
min-height: 200px;
}
}
}
.secondBlock {
width: 30%;
background-color: #fff;
display: flex;
flex-direction: column;
padding: 10px 16px;
border-radius: 2px;
.chartHeader {
display: flex;
align-items: center;
margin-bottom: 16px;
// height: 18px;
.colorBlock {
width: 2px;
height: 18px;
background-color: #2E4CD4;
margin-right: 8px;
border-radius: 1px;
}
.chartTitle {
font-size: 16px;
font-weight: 500;
color: #333333;
line-height: 18px;
}
}
}
.thirdBlock {
flex: 1;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
color: #333;
}
}
.listCard {
border: none;
border-radius: 8px;
box-shadow: none;
.listTitle {
margin-bottom: 20px;
font-size: 16px;
font-weight: 600;
color: #333;
}
.listToolbar {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 20px;
.searchInput {
width: 300px;
}
.typeFilter {
width: 120px;
}
.addButton {
margin-left: auto;
}
}
.licenseTable {
.ant-table-thead>tr>th {
background-color: #fafafa;
font-weight: 600;
color: #333;
}
.ant-table-tbody>tr>td {
border-bottom: 1px solid #f0f0f0;
}
.ant-pagination {
margin-top: 20px;
text-align: right;
}
}
}
}
// 覆盖Ant Design默认样式
.licenseManagementContainer {
.ant-card {
box-shadow: none;
}
.ant-card-body {
padding: 20px;
}
.ant-table {
font-size: 14px;
}
.ant-tag {
border-radius: 4px;
font-size: 12px;
padding: 2px 8px;
}
.ant-btn-link {
padding: 0;
height: auto;
font-size: 14px;
}
.ant-input-search {
.ant-input {
border-radius: 6px;
}
}
.ant-select {
.ant-select-selector {
border-radius: 6px;
}
}
.ant-btn-primary {
border-radius: 6px;
}
}
Loading…
Cancel
Save