194 lines
5.4 KiB
JavaScript
194 lines
5.4 KiB
JavaScript
|
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|||
|
|
import { Button, Form, Input, message, Space } from 'antd';
|
|||
|
|
import {
|
|||
|
|
CheckCircleFilled,
|
|||
|
|
FileSearchOutlined,
|
|||
|
|
LoadingOutlined,
|
|||
|
|
SafetyCertificateFilled
|
|||
|
|
} from '@ant-design/icons';
|
|||
|
|
import './index.css';
|
|||
|
|
import { materialFields, materialInitialValues, mockSubmitMaterial } from './mockData';
|
|||
|
|
|
|||
|
|
const steps = [
|
|||
|
|
{ key: 1, title: '填写信息' },
|
|||
|
|
{ key: 2, title: '认证审核中' },
|
|||
|
|
{ key: 3, title: '认证通过' }
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
function PageHeader() {
|
|||
|
|
return (
|
|||
|
|
<div className="material-report-header">
|
|||
|
|
<div className="material-report-brand">
|
|||
|
|
<span className="material-report-logo"><SafetyCertificateFilled /></span>
|
|||
|
|
<span>巫溪县安全评价在线监管一件事</span>
|
|||
|
|
</div>
|
|||
|
|
<div className="material-report-hero">
|
|||
|
|
<h1>认证信息</h1>
|
|||
|
|
<div className="material-report-hero-art">
|
|||
|
|
<div className="verify-platform"><CheckCircleFilled /></div>
|
|||
|
|
<div className="verify-card" />
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function StepHeader({ current }) {
|
|||
|
|
return (
|
|||
|
|
<div className="material-report-steps">
|
|||
|
|
{steps.map((step, index) => {
|
|||
|
|
const active = current >= step.key;
|
|||
|
|
const currentStep = current === step.key;
|
|||
|
|
return (
|
|||
|
|
<div key={step.key} className={`material-step ${active ? 'is-active' : ''} ${currentStep ? 'is-current' : ''}`}>
|
|||
|
|
<span className="material-step__dot">{step.key}</span>
|
|||
|
|
<span className="material-step__title">{step.title}</span>
|
|||
|
|
{index < steps.length - 1 && <i className="material-step__line" />}
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
})}
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function FieldItem({ field }) {
|
|||
|
|
const labelLines = field.label.split('\n');
|
|||
|
|
return (
|
|||
|
|
<div className={`material-form-field material-form-field--${field.span}`}>
|
|||
|
|
<Form.Item
|
|||
|
|
name={field.name}
|
|||
|
|
label={(
|
|||
|
|
<span>
|
|||
|
|
{labelLines.map((line) => <React.Fragment key={line}>{line}<br /></React.Fragment>)}
|
|||
|
|
</span>
|
|||
|
|
)}
|
|||
|
|
rules={field.span === 24 ? [{ required: true, message: `请输入${labelLines[0]}` }] : undefined}
|
|||
|
|
>
|
|||
|
|
<Input />
|
|||
|
|
</Form.Item>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function FillStep({ onSubmitted }) {
|
|||
|
|
const [form] = Form.useForm();
|
|||
|
|
const [submitting, setSubmitting] = useState(false);
|
|||
|
|
|
|||
|
|
const groupedRows = useMemo(() => {
|
|||
|
|
const rows = [];
|
|||
|
|
let current = [];
|
|||
|
|
let used = 0;
|
|||
|
|
materialFields.forEach((field) => {
|
|||
|
|
if (field.span === 24) {
|
|||
|
|
if (current.length) rows.push(current);
|
|||
|
|
rows.push([field]);
|
|||
|
|
current = [];
|
|||
|
|
used = 0;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (used + field.span > 24) {
|
|||
|
|
rows.push(current);
|
|||
|
|
current = [];
|
|||
|
|
used = 0;
|
|||
|
|
}
|
|||
|
|
current.push(field);
|
|||
|
|
used += field.span;
|
|||
|
|
});
|
|||
|
|
if (current.length) rows.push(current);
|
|||
|
|
return rows;
|
|||
|
|
}, []);
|
|||
|
|
|
|||
|
|
const handleSubmit = async () => {
|
|||
|
|
try {
|
|||
|
|
const values = await form.validateFields();
|
|||
|
|
setSubmitting(true);
|
|||
|
|
const res = await mockSubmitMaterial(values);
|
|||
|
|
if (res?.success) {
|
|||
|
|
message.success('提交成功,正在进入认证审核');
|
|||
|
|
onSubmitted(res.data);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (err) {
|
|||
|
|
if (!err?.errorFields) {
|
|||
|
|
message.error('提交失败,请稍后重试');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
finally {
|
|||
|
|
setSubmitting(false);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="material-fill-step">
|
|||
|
|
<Form form={form} initialValues={materialInitialValues} colon={false} labelAlign="right">
|
|||
|
|
<div className="material-form-grid">
|
|||
|
|
{groupedRows.map((row, index) => (
|
|||
|
|
<div key={index} className="material-form-row">
|
|||
|
|
{row.map((field) => <FieldItem key={field.name} field={field} />)}
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
</Form>
|
|||
|
|
<div className="material-form-actions">
|
|||
|
|
<Space size={10}>
|
|||
|
|
<Button>取消</Button>
|
|||
|
|
<Button className="material-save-btn">保存</Button>
|
|||
|
|
<Button type="primary" loading={submitting} onClick={handleSubmit}>提交</Button>
|
|||
|
|
</Space>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ReviewLoadingStep() {
|
|||
|
|
return (
|
|||
|
|
<div className="material-result-wrap">
|
|||
|
|
<div className="review-loading-icon">
|
|||
|
|
<div className="review-loading-ring" />
|
|||
|
|
<FileSearchOutlined />
|
|||
|
|
<span />
|
|||
|
|
</div>
|
|||
|
|
<p>认证审核中,请耐心等待...</p>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ReviewSuccessStep() {
|
|||
|
|
return (
|
|||
|
|
<div className="material-result-wrap material-success-wrap">
|
|||
|
|
<div className="review-success-illustration">
|
|||
|
|
<div className="success-paper">
|
|||
|
|
<i /><i /><i /><i />
|
|||
|
|
</div>
|
|||
|
|
<CheckCircleFilled />
|
|||
|
|
</div>
|
|||
|
|
<p>审核通过</p>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default function MaterialReportPage() {
|
|||
|
|
const [current, setCurrent] = useState(1);
|
|||
|
|
const timerRef = useRef(null);
|
|||
|
|
|
|||
|
|
useEffect(() => () => clearTimeout(timerRef.current), []);
|
|||
|
|
|
|||
|
|
const handleSubmitted = () => {
|
|||
|
|
setCurrent(2);
|
|||
|
|
clearTimeout(timerRef.current);
|
|||
|
|
timerRef.current = setTimeout(() => {
|
|||
|
|
setCurrent(3);
|
|||
|
|
}, 2300);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className={`material-report-page material-report-page--step-${current}`}>
|
|||
|
|
<PageHeader />
|
|||
|
|
<StepHeader current={current} />
|
|||
|
|
{current === 1 && <FillStep onSubmitted={handleSubmitted} />}
|
|||
|
|
{current === 2 && <ReviewLoadingStep />}
|
|||
|
|
{current === 3 && <ReviewSuccessStep />}
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|