Compare commits

...

2 Commits

Author SHA1 Message Date
wangyunfei 8ea3aaff13 高度 2 weeks ago
wangyunfei 1dd2639806 资质证照页面 2 weeks ago

@ -1,13 +1,18 @@
import React, { useEffect, useRef } from 'react';
import { Card, Table, Tag, Space, Typography, Progress, Row, Col, Button } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { Card, Table, Tag, Space, Typography, Progress, Row, Col, Button, Input, Select } from 'antd';
import * as echarts from 'echarts';
import StandardTable from '@/components/StandardTable';
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 [searchValue, setSearchValue] = useState('');
const [selectedType, setSelectedType] = useState('all');
// 图表数据
const chartData = [
@ -130,7 +135,7 @@ const LicenseManagement = () => {
id: 'HQ-XF-02-015',
authority: '第三方评估机构',
validUntil: '2025-09-10',
status: '15天后到期',
status: '有效',
statusType: 'warning'
},
{
@ -154,6 +159,72 @@ const LicenseManagement = () => {
validUntil: '2025-09-10',
status: '有效',
statusType: 'success'
},
{
key: '5',
no: '05',
name: '消防验收合格证',
type: '消防证书',
id: 'HQ-XF-05-012',
authority: '消防局',
validUntil: '2026-03-15',
status: '有效',
statusType: 'success'
},
{
key: '6',
no: '06',
name: '职业健康安全管理体系认证',
type: '管理体系认证',
id: 'HQ-XF-06-008',
authority: '认证机构',
validUntil: '2026-06-20',
status: '有效',
statusType: 'success'
},
{
key: '7',
no: '07',
name: '环境管理体系认证',
type: '管理体系认证',
id: 'HQ-XF-07-009',
authority: '认证机构',
validUntil: '2026-08-25',
status: '有效',
statusType: 'success'
},
{
key: '8',
no: '08',
name: '特种设备使用登记证',
type: '特种设备证书',
id: 'HQ-XF-08-011',
authority: '质量技术监督局',
validUntil: '2026-12-10',
status: '有效',
statusType: 'success'
},
{
key: '9',
no: '09',
name: '危险化学品经营许可证',
type: '经营许可证',
id: 'HQ-XF-09-013',
authority: '应急管理局',
validUntil: '2027-01-30',
status: '有效',
statusType: 'success'
},
{
key: '10',
no: '10',
name: '辐射安全许可证',
type: '辐射安全证书',
id: 'HQ-XF-10-014',
authority: '生态环境部',
validUntil: '2027-04-18',
status: '有效',
statusType: 'success'
}
];
@ -200,23 +271,96 @@ const LicenseManagement = () => {
dataIndex: 'status',
key: 'status',
width: 120,
render: (text, record) => (
<Tag color={record.statusType === 'success' ? 'green' :
record.statusType === 'warning' ? 'orange' : 'red'}>
render: (text, record) => {
const getStatusStyle = (status) => {
if (status === '有效') {
return {
color: '#44BB5F',
backgroundColor: '#D8F7DE',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
display: 'inline-block'
};
} else if (status === '即将到期') {
return {
color: '#FF8800',
backgroundColor: '#FFF3E9',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
display: 'inline-block'
};
} else if (status === '已过期') {
return {
color: '#FF3E48',
backgroundColor: '#FFE0E2',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px',
display: 'inline-block'
};
}
return {};
};
return (
<span style={getStatusStyle(text)}>
{text}
</Tag>
),
</span>
);
}
},
{
title: '操作',
dataIndex: 'action',
key: 'action',
width: 120,
render: () => (
<Space size="small">
<Button type="link" size="small">更新</Button>
<Button type="link" size="small">查看</Button>
</Space>
),
render: (text, record) => {
const handleEdit = (record) => {
console.log('编辑记录:', record);
};
const handleDelete = (record) => {
console.log('删除记录:', record);
};
return (
<div style={{
display: 'flex',
gap: '8px',
justifyContent: 'center',
alignItems: 'center'
}}>
<Button
onClick={() => handleEdit(record)}
style={{
color: '#2E4CD4',
backgroundColor: 'transparent',
// borderColor: '#E6E9FB',
fontSize: '12px',
height: '28px',
padding: '0 12px'
}}
>
更新
</Button>
<Button
onClick={() => handleDelete(record)}
style={{
color: '#2E4CD4',
backgroundColor: 'transparent',
// borderColor: '#E6E9FB',
fontSize: '12px',
height: '28px',
padding: '0 12px'
}}
>
查看
</Button>
</div>
);
}
},
];
@ -238,7 +382,7 @@ const LicenseManagement = () => {
<div className={styles.secondBlock}>
<div className={styles.chartHeader}>
<div className={styles.colorBlock}></div>
<span className={styles.chartTitle}>证件类型分布</span>
<span className={styles.chartTitle}>证件状态概览</span>
</div>
<div className={styles.chartContainer}>
{/* 上半部分:进度条和百分比 */}
@ -391,21 +535,66 @@ const LicenseManagement = () => {
{/* 证照列表区域 */}
<div className={styles.listCard}>
<div className={styles.chartHeader}>
<div className={styles.headerLeft}>
<div className={styles.colorBlock}></div>
<span className={styles.chartTitle}>证照列表</span>
</div>
<Table
<div className={styles.headerRight}>
<Search
placeholder="搜索证照名称或编号..."
value={searchValue}
onChange={(e) => setSearchValue(e.target.value)}
onSearch={(value) => console.log('搜索:', value)}
className={styles.searchInput}
/>
<Select
value={selectedType}
onChange={setSelectedType}
className={styles.typeSelector}
>
<Option value="all">全部类型</Option>
<Option value="safety">安全生产许可证</Option>
<Option value="assessment">安全评估报告</Option>
<Option value="construction">施工资质证书</Option>
<Option value="emergency">应急预案</Option>
<Option value="other">其他</Option>
</Select>
<Button
type="primary"
className={styles.addButton}
onClick={() => console.log('新增证照')}
>
新增证照
</Button>
</div>
</div>
<StandardTable
columns={columns}
dataSource={tableData}
data={{
list: tableData, // ======== 表格数据列表 ========
pagination: { // ======== 分页配置 ========
currentPage: 1, // ======== 当前页码 ========
pageSize: 5, // ======== 每页显示5条数据 ========
total: tableData.length, // ======== 总数据条数 ========
} // ======== 分页配置结束 ========
}} // ======== 数据对象结束 ========
selectedRows={[]} // ======== 选中的行数据,初始为空数组 ========
onSelectRow={() => { }} // ======== 行选择事件处理函数 ========
onChange={() => { }} // ======== 表格变化事件处理函数 ========
pagination={{
current: 3,
total: 48,
pageSize: 10,
currentPage: 1,
pageSize: 5,
total: tableData.length,
showSizeChanger: false,
showQuickJumper: true,
showTotal: (total) => `${total}`,
showTotal: (total, range) =>
`${total}`,
locale: {
jump_to: '前往',
page: '页',
items_per_page: '条/页',
}
}}
className={styles.licenseTable}
/>
</div>
</div>

@ -1,10 +1,10 @@
.licenseManagementContainer {
height: 100vh;
height: 90vh;
.topSectionContainer {
padding: 0;
margin: 15px 0px 15px 5px;
height: 35%;
height: 40%;
display: flex;
gap: 15px;
align-items: stretch;
@ -31,7 +31,7 @@
}
.chartTitle {
font-size: 16px;
font-size: 14px;
font-weight: 500;
color: #333333;
line-height: 18px;
@ -140,7 +140,7 @@
}
.chartTitle {
font-size: 16px;
font-size: 14px;
font-weight: 500;
color: #333333;
// line-height: 18px;
@ -247,7 +247,7 @@
}
.chartTitle {
font-size: 16px;
font-size: 14px;
font-weight: 500;
color: #333333;
}
@ -325,7 +325,7 @@
.listCard {
padding: 0;
padding: 15px 5px 15px 20px;
height: 35%;
flex: 1;
// display: flex;
gap: 15px;
background-color: #fff;
@ -334,7 +334,12 @@
.chartHeader {
display: flex;
align-items: center;
margin-bottom: 8px;
justify-content: space-between;
margin-bottom: 16px;
.headerLeft {
display: flex;
align-items: center;
.colorBlock {
width: 2px;
@ -348,25 +353,103 @@
font-size: 14px;
font-weight: 500;
color: #333333;
line-height: 18px;
}
}
.licenseTable {
.ant-table-thead>tr>th {
background-color: #F5F5FA;
font-weight: 200;
color: #333333;
.headerRight {
display: flex;
align-items: center;
gap: 12px;
.searchInput {
width: 280px;
.ant-input {
border-radius: 2px;
border: 1px solid #d9d9d9;
&:hover {
border-color: #40a9ff;
}
&:focus {
border-color: #40a9ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
}
}
.typeSelector {
width: 120px;
.ant-table-tbody>tr>td {
.ant-select-selector {
border-radius: 2px;
border: 1px solid #d9d9d9;
&:hover {
border-color: #40a9ff;
}
}
&.ant-select-focused .ant-select-selector {
border-color: #40a9ff;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
}
.addButton {
border-radius: 4px;
background-color: #2E4CD4;
// border-color: #1890ff;
height: 32px;
padding: 4px 15px;
font-size: 14px;
display: flex;
align-items: center;
justify-content: center;
&:hover {
background-color: #2E4CD4;
// border-color: #40a9ff;
}
&:focus {
background-color: #2E4CD4;
// border-color: #40a9ff;
}
}
}
}
// StandardTable 组件样式
:global(.ant-table) {
font-size: 12px;
}
:global(.ant-pagination-options-quick-jumper input) {
text-align: center !important;
}
:global(.ant-table-thead > tr > th) {
background-color: #f5f5fa;
font-weight: 500;
font-size: 14px;
color: #333333;
border-bottom: 1px solid #f0f0f0;
padding: 8px 12px;
text-align: center;
}
.ant-pagination {
margin-top: 20px;
text-align: right;
:global(.ant-table-tbody > tr > td) {
padding: 8px 12px;
border-bottom: 1px solid #f0f0f0;
text-align: center;
color: #666666;
}
:global(.ant-pagination) {
margin-top: 16px;
text-align: right;
}
}
}

Loading…
Cancel
Save