main
wangyunfei888 1 month ago
parent adcc67002e
commit ddeafd1288

@ -89,7 +89,7 @@ const TemplateCreate = () => {
<div className={styles.rightPanel}>
<div className={styles.rightHeader}>
<span>样式</span>
<Button type="primary">生成报表</Button>
<Button type="primary" className={styles.reportBtn}>生成报表</Button>
</div>
<div className={styles.formSection}>

@ -219,6 +219,20 @@
color: #333;
}
.reportBtn {
background: rgba(22, 22, 22, 1);
color: #fff;
border-color: rgba(22, 22, 22, 1);
border-radius: 4px;
&:hover,
&:focus {
background: rgba(22, 22, 22, 1);
color: #fff;
border-color: rgba(22, 22, 22, 1);
}
}
.formSection {
display: flex;
flex-direction: column;

@ -1,5 +1,5 @@
import React, {useMemo, useState} from 'react';
import {Badge, Button, DatePicker, Form, Row, Col, Select, Space} from 'antd';
import {Badge, Button, DatePicker, Select, Space} from 'antd';
import ReactECharts from 'echarts-for-react';
import StandardTable from '@/components/StandardTable';
import './LedgerCenter.less';
@ -34,26 +34,15 @@ const LedgerCenter = () => {
dataIndex: 'sourceType',
width: 140,
render: type => (
<Button size="small" ghost={type !== '在线监测设备'} type={type === '在线监测设备' ? 'primary' : 'dashed'}>
<Button
size="small"
type="default"
className={`source-tag ${type === '在线监测设备' ? 'source-online' : 'source-manual'}`}
>
{type}
</Button>
),
},
{
title: '操作',
dataIndex: 'actions',
align: 'right',
render: () => (
<Space size={8}>
<Button size="small" type="link">
详情
</Button>
<Button size="small" type="link">
查看报表
</Button>
</Space>
),
},
],
data: [
{
@ -233,27 +222,32 @@ const LedgerCenter = () => {
return (
<div className="ledger-center">
<div className="ledger-block filter-block">
<Form layout="vertical">
<Row gutter={16} className="filter-row">
<Col span={8}>
<Form.Item label="模版名称">
<Select placeholder="请选择模版" options={[{label: '污染源排放台账', value: 'ledger1'}, {label: '废水排放台账', value: 'ledger2'}]} />
</Form.Item>
</Col>
<Col span={10}>
<Form.Item label="起止时间">
<RangePicker style={{width: '100%'}} />
</Form.Item>
</Col>
<Col span={6}>
<Form.Item label="所属区域">
<Select placeholder="请选择区域" options={[{label: '全部区域', value: 'all'}, {label: '能源车间', value: 'energy'}, {label: '污水处理站', value: 'water'}]} />
</Form.Item>
</Col>
</Row>
<Row gutter={16} className="filter-row">
<Col span={16}>
<Form.Item label="填报单位">
<div className="filter-line first-line">
<div className="filter-item">
<span className="filter-label">模版名称</span>
<Select
placeholder="请选择模版"
options={[{label: '污染源排放台账', value: 'ledger1'}, {label: '废水排放台账', value: 'ledger2'}]}
className="filter-control"
/>
</div>
<div className="filter-item">
<span className="filter-label">起止时间</span>
<RangePicker className="filter-control" />
</div>
<div className="filter-item">
<span className="filter-label">所属区域</span>
<Select
placeholder="请选择区域"
options={[{label: '全部区域', value: 'all'}, {label: '能源车间', value: 'energy'}, {label: '污水处理站', value: 'water'}]}
className="filter-control"
/>
</div>
</div>
<div className="filter-line second-line">
<div className="filter-item wide">
<span className="filter-label">填报单位</span>
<Select
mode="multiple"
allowClear
@ -264,17 +258,17 @@ const LedgerCenter = () => {
{label: '单位3', value: 'unit3'},
{label: '单位4', value: 'unit4'},
]}
className="filter-control"
/>
</Form.Item>
</Col>
</Row>
<div className="filter-actions">
<Space size={10}>
<Button>重新配置</Button>
<Button type="primary">生成台账</Button>
</Space>
</div>
</Form>
</div>
<div className="filter-line action-line">
<div className="action-buttons">
<Button className="reset-btn">重新配置</Button>
<Button type="primary" className="generate-btn">生成台账</Button>
</div>
</div>
</div>
<div className="ledger-block table-block">
@ -291,9 +285,9 @@ const LedgerCenter = () => {
</Button>
</Space>
<Space size={10}>
<Button type="link">Excel 导出</Button>
<Button type="link" className="excel-btn">Excel 导出</Button>
<Button>保存为快照</Button>
<Button type="primary">发起报告</Button>
<Button>发起报告</Button>
</Space>
</div>

@ -9,20 +9,104 @@
.ledger-block {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
padding: 16px;
border: 1px solid #f0f0f0;
box-shadow: none;
padding: 14px 16px;
}
.filter-block {
display: flex;
flex-direction: column;
gap: 12px;
}
.filter-line {
display: flex;
align-items: center;
gap: 16px;
}
.first-line .filter-item {
flex: 1;
max-width: 33%;
}
.second-line .filter-item {
flex: 1;
}
.action-line {
justify-content: center;
align-items: center;
}
.filter-item {
display: flex;
align-items: center;
gap: 8px;
}
.filter-label {
min-width: 72px;
color: #333;
font-size: 14px;
}
.filter-control {
min-width: 220px;
}
.first-line .filter-item:nth-child(2) .filter-control {
min-width: 220px;
}
.first-line .filter-item:nth-child(3) .filter-control {
min-width: 200px;
}
.filter-row {
margin-bottom: 8px;
.filter-control .ant-select-selector,
.filter-control.ant-picker,
.filter-control.ant-select {
width: 100%;
}
.filter-actions {
padding-top: 4px;
.action-buttons {
display: flex;
gap: 12px;
align-items: center;
}
.filter-actions .ant-btn {
min-width: 104px;
.action-buttons .ant-btn {
min-width: 120px;
// height: 28px;
line-height: 28px;
border-radius: 4px;
}
.reset-btn {
background: #f5f5f5;
color: #666;
border-color: #e5e5e5;
&:hover,
&:focus {
background: #f5f5f5;
color: #666;
border-color: #e5e5e5;
}
}
.generate-btn {
background: rgba(0, 200, 122, 1);
border-color: rgba(0, 200, 122, 1);
color: #fff;
&:hover,
&:focus {
background: rgba(0, 200, 122, 1);
border-color: rgba(0, 200, 122, 1);
color: #fff;
}
}
.table-toolbar {
@ -37,6 +121,81 @@
margin-top: 12px;
}
.table-block {
.ant-table-wrapper {
border: 1px solid #f0f0f0;
border-radius: 6px;
}
.ant-table-container {
border-radius: 6px;
}
.ant-table-thead > tr > th {
background: #fafafa;
color: #333;
font-weight: 500;
height: 42px;
border-color: #f0f0f0;
}
.ant-table-tbody > tr > td {
height: 46px;
border-color: #f0f0f0;
color: #333;
}
.ant-table-tbody > tr:hover > td {
background: #fafafa;
}
.ant-pagination {
display: flex;
justify-content: center;
margin-top: 16px;
}
.ant-pagination-item-active {
border-color: rgba(0, 200, 122, 1);
background: rgba(0, 200, 122, 1);
a {
color: #fff;
}
}
}
.source-tag {
padding: 0 10px;
height: 24px;
line-height: 22px;
border-radius: 4px;
border: 1px solid transparent;
box-shadow: none;
font-size: 12px;
}
.source-online {
background: rgba(3, 197, 152, 1);
border-color: rgba(3, 197, 152, 1);
color: #fff;
}
.source-manual {
background: #fff9e6;
border-color: #f2d28b;
color: #d48806;
}
.excel-btn {
color: rgba(3, 197, 152, 1);
&:hover,
&:focus {
color: rgba(3, 197, 152, 1);
}
}
.chart-wrapper {
padding: 8px 0 0;
}

@ -9,8 +9,6 @@ const { RangePicker } = DatePicker;
const ReportTask = () => {
const [status, setStatus] = useState();
const [template, setTemplate] = useState();
const [type, setType] = useState();
const [period, setPeriod] = useState(null);
const [createdAt, setCreatedAt] = useState(null);
const [page, setPage] = useState(6);
@ -18,10 +16,16 @@ const ReportTask = () => {
const [detailItem, setDetailItem] = useState(null);
const statusMeta = {
审核失败: { color: 'orange', text: '审核失败' },
待提交: { color: 'gold', text: '待提交' },
已提交: { color: 'green', text: '已提交' },
校验失败: { color: 'red', text: '校验失败' },
审核失败: { dot: '#f85c3d', text: '审核失败' },
待提交: { dot: '#f8c349', text: '待提交' },
已提交: { dot: '#48c774', text: '已提交' },
校验失败: { dot: '#e14c49', text: '校验失败' },
};
const actionMeta = {
提交: { color: '#ffac46' },
催办: { color: '#e14c49' },
下载: { color: '#8c8c8c' },
};
const dataSource = useMemo(
@ -70,25 +74,32 @@ const ReportTask = () => {
[],
);
const renderHeader = (label) => (
<span className="table-header-title">
{label}
<SearchOutlined className="header-search-icon" />
</span>
);
const columns = [
{
title: '序号',
title: renderHeader('序号'),
dataIndex: 'id',
width: 70,
align: 'center',
},
{
title: '任务名称',
title: renderHeader('任务名称'),
dataIndex: 'name',
ellipsis: true,
},
{
title: '报送模板',
title: renderHeader('报送模板'),
dataIndex: 'template',
ellipsis: true,
},
{
title: '类型',
title: renderHeader('类型'),
dataIndex: 'type',
width: 90,
align: 'center',
@ -97,44 +108,45 @@ const ReportTask = () => {
),
},
{
title: '上次报送时间',
title: renderHeader('上次报送时间'),
dataIndex: 'lastReport',
width: 140,
align: 'center',
},
{
title: '下次报送时间',
title: renderHeader('下次报送时间'),
dataIndex: 'nextReport',
width: 140,
align: 'center',
},
{
title: '状态',
title: renderHeader('状态'),
dataIndex: 'status',
width: 120,
align: 'center',
render: (value) => {
const meta = statusMeta[value] || {};
return (
<Tag color={meta.color} className="status-tag">
<span className="status-dot" />
{meta.text}
<Tag className="status-tag">
<span className="status-dot" style={{ background: meta.dot }} />
<span className="status-text">{meta.text}</span>
</Tag>
);
},
},
{
title: '操作',
title: renderHeader('操作'),
dataIndex: 'action',
width: 160,
align: 'center',
render: (action, record) => {
const isUrge = action === '催办';
const meta = actionMeta[action] || {};
return (
<div className="action-links">
<Button
type="link"
size="small"
className="link-detail"
onClick={() => {
setDetailItem(record);
setDetailVisible(true);
@ -142,7 +154,7 @@ const ReportTask = () => {
>
详情
</Button>
<Button type="link" size="small" danger={isUrge}>
<Button type="link" size="small" className="link-action" style={{ color: meta.color }}>
{action}
</Button>
</div>
@ -152,7 +164,7 @@ const ReportTask = () => {
];
const handleSearch = () => {
console.log('查找', { status, template, type, period, createdAt });
console.log('查找', { status, period, createdAt });
};
const handleCreate = () => {
@ -188,36 +200,6 @@ const ReportTask = () => {
</Select>
</div>
<div className="filter-item">
<span className="filter-label">报送模板</span>
<Select
placeholder="请选择"
allowClear
value={template}
onChange={setTemplate}
className="filter-control"
>
<Option value="污染物排放台账">污染物排放台账</Option>
<Option value="危险废物管理台账">危险废物管理台账</Option>
<Option value="运行记录">运行记录</Option>
<Option value="排污许可证">排污许可证</Option>
</Select>
</div>
<div className="filter-item">
<span className="filter-label">类型</span>
<Select
placeholder="请选择"
allowClear
value={type}
onChange={setType}
className="filter-control"
>
<Option value="月度">月度</Option>
<Option value="年度">年度</Option>
</Select>
</div>
<div className="filter-item">
<span className="filter-label">报送周期</span>
<RangePicker
@ -246,10 +228,24 @@ const ReportTask = () => {
<div className="table-wrapper">
<Table
bordered
columns={columns}
dataSource={dataSource}
rowKey="id"
pagination={{ current: page, pageSize: 5, total: 85, onChange: setPage }}
className="report-task-table"
size="middle"
tableLayout="fixed"
pagination={{
current: page,
pageSize: 5,
total: 85,
showSizeChanger: true,
pageSizeOptions: ['5', '10', '20'],
showQuickJumper: false,
showTotal: (total) => `${total}`,
onChange: setPage,
}}
rowClassName={() => 'report-task-row'}
/>
</div>

@ -7,13 +7,18 @@
.toolbar {
display: flex;
align-items: center;
justify-content: space-between;
justify-content: flex-start;
gap: 12px;
background: #fff;
border: 1px solid #f0f0f0;
border-radius: 4px;
padding: 12px 16px;
.create-btn {
display: inline-flex;
align-items: center;
gap: 6px;
white-space: nowrap;
background: rgba(0, 212, 138, 1);
border-color: rgba(0, 212, 138, 1);
color: #fff;
@ -29,9 +34,12 @@
.filter-group {
display: flex;
flex-wrap: wrap;
flex: 1;
flex-wrap: nowrap;
align-items: center;
gap: 12px;
overflow-x: auto;
min-height: 32px;
.filter-item {
display: inline-flex;
@ -45,11 +53,17 @@
}
.filter-control {
width: 180px;
width: 120px !important;
min-width: 120px;
}
.filter-control.ant-select .ant-select-selector {
width: 120px;
}
.ant-picker-range {
width: 260px;
.filter-control.ant-picker-range {
width: 120px !important;
min-width: 120px;
}
}
@ -73,16 +87,53 @@
padding: 12px 16px 16px;
overflow: hidden;
.table-header-title {
display: inline-flex;
align-items: center;
gap: 6px;
color: #1f1f1f;
font-weight: 500;
}
.header-search-icon {
color: #c6c6c6;
font-size: 12px;
}
.report-task-table {
.ant-table-thead > tr > th {
background: #f5f7fa;
color: #1f1f1f;
font-weight: 500;
border-bottom: 1px solid #e9e9e9;
padding: 12px 10px;
}
.ant-table-tbody > tr > td {
border-bottom: 1px solid #f0f0f0;
padding: 12px 10px;
}
.ant-table-tbody > tr:hover > td {
background: #f8fbff;
}
.ant-table-pagination-right {
justify-content: flex-end;
}
}
.ant-table {
.status-tag {
display: inline-flex;
align-items: center;
gap: 6px;
border: none;
border: 1px solid #f0f0f0;
border-radius: 2px;
height: 26px;
padding: 0 10px;
font-size: 12px;
background: #fff;
}
.status-dot {
@ -98,6 +149,10 @@
border-radius: 2px;
padding: 2px 10px;
font-size: 12px;
height: 26px;
display: inline-flex;
align-items: center;
line-height: 1;
}
.type-monthly {
@ -118,6 +173,14 @@
.ant-btn-link {
padding: 0 6px;
}
.link-detail {
color: #25b864;
}
.link-action {
font-weight: 500;
}
}
}
}

@ -29,6 +29,10 @@ const menuItem = [
label: '环保活动管理',
key: '/topnavbar00/business/environmentalActivities',
},
{
label: '环保月报管理-模板库新建',
key: '/topnavbar00/business/envInformationMonthly/template-create',
},
]
const TopNavBar = (props) => {

Loading…
Cancel
Save