|
|
@ -7,8 +7,8 @@ import { |
|
|
|
dnsVerifyOKAtom, |
|
|
|
saveOrUpdateCertAtom, |
|
|
|
} from "@/store/websites/cert.ts"; |
|
|
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; |
|
|
|
import { Button, Flex, Form, Input, Progress, Select, Space, Table, Tooltip } from "antd"; |
|
|
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; |
|
|
|
import {Button, Flex, Form, Input, message, Progress, Radio, Select, Space, Steps, Table, Tooltip} from "antd"; |
|
|
|
import google from "@/pages/websites/cert/assets/google.png"; |
|
|
|
import zerossl from "@/pages/websites/cert/assets/zerossl.png"; |
|
|
|
import lets_encrypt from "@/pages/websites/cert/assets/lets_encrypt.png"; |
|
|
@ -17,7 +17,7 @@ import ListPageLayout from "@/layout/ListPageLayout.tsx"; |
|
|
|
import { ColumnsType } from "antd/es/table"; |
|
|
|
import { atomWithStorage } from "jotai/utils"; |
|
|
|
import Copy from "@/components/copy"; |
|
|
|
import { InfoCircleOutlined, LoadingOutlined } from "@ant-design/icons"; |
|
|
|
import { CopyOutlined, InfoCircleOutlined, LoadingOutlined } from "@ant-design/icons"; |
|
|
|
|
|
|
|
const i18nPrefix = "cert.apply"; |
|
|
|
|
|
|
@ -34,45 +34,45 @@ const BrandSelect = (props: any) => { |
|
|
|
}, []); |
|
|
|
|
|
|
|
return ( |
|
|
|
<> |
|
|
|
<Space className={styles.bandSelect}> |
|
|
|
<Flex |
|
|
|
vertical={true} |
|
|
|
onClick={() => onChange("Google")} |
|
|
|
className={cx("band-normal", { |
|
|
|
"band-active": value === "Google", |
|
|
|
})} |
|
|
|
> |
|
|
|
<img src={google} style={{ height: "2rem" }} /> |
|
|
|
<span>Google Trust Services</span> |
|
|
|
</Flex> |
|
|
|
<Flex |
|
|
|
vertical={true} |
|
|
|
onClick={() => onChange("ZeroSSL")} |
|
|
|
className={cx("band-normal", { |
|
|
|
"band-active": value === "ZeroSSL", |
|
|
|
})} |
|
|
|
> |
|
|
|
<img src={zerossl} style={{ height: "2rem" }} /> |
|
|
|
<span>ZeroSSL</span> |
|
|
|
</Flex> |
|
|
|
<Flex |
|
|
|
vertical={true} |
|
|
|
onClick={() => onChange("Let's Encrypt")} |
|
|
|
className={cx("band-normal", { |
|
|
|
"band-active": value === "Let's Encrypt", |
|
|
|
})} |
|
|
|
> |
|
|
|
<img src={lets_encrypt} style={{ height: "2rem" }} /> |
|
|
|
<span>Let's Encrypt</span> |
|
|
|
</Flex> |
|
|
|
</Space> |
|
|
|
</> |
|
|
|
<> |
|
|
|
<Space className={styles.bandSelect}> |
|
|
|
<Flex |
|
|
|
vertical={true} |
|
|
|
onClick={() => onChange("Google")} |
|
|
|
className={cx("band-normal", { |
|
|
|
"band-active": value === "Google" || !props.value, |
|
|
|
})} |
|
|
|
> |
|
|
|
<img src={google} style={{ height: "2rem" }} /> |
|
|
|
<span>Google Trust Services</span> |
|
|
|
</Flex> |
|
|
|
<Flex |
|
|
|
vertical={true} |
|
|
|
onClick={() => onChange("ZeroSSL")} |
|
|
|
className={cx("band-normal", { |
|
|
|
"band-active": value === "ZeroSSL", |
|
|
|
})} |
|
|
|
> |
|
|
|
<img src={zerossl} style={{ height: "2rem" }} /> |
|
|
|
<span>ZeroSSL</span> |
|
|
|
</Flex> |
|
|
|
<Flex |
|
|
|
vertical={true} |
|
|
|
onClick={() => onChange("Let's Encrypt")} |
|
|
|
className={cx("band-normal", { |
|
|
|
"band-active": value === "Let's Encrypt", |
|
|
|
})} |
|
|
|
> |
|
|
|
<img src={lets_encrypt} style={{ height: "2rem" }} /> |
|
|
|
<span>Let's Encrypt</span> |
|
|
|
</Flex> |
|
|
|
</Space> |
|
|
|
</> |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
const StatusTable = (props: { value: string }) => { |
|
|
|
const [data, setData] = useState<any>(null); // 临时状态来存储模拟数据
|
|
|
|
const [data, setData] = useState<any>(null); // 临时状态来存储模拟数据
|
|
|
|
const { isFetching } = useAtomValue(useMemo(() => dnsConfigAtom(props.value), [props.value])); |
|
|
|
|
|
|
|
const { |
|
|
@ -85,16 +85,24 @@ const StatusTable = (props: { value: string }) => { |
|
|
|
|
|
|
|
const timerRef = useRef<number>(); |
|
|
|
|
|
|
|
const handleCopy = (str:string) => { |
|
|
|
navigator.clipboard.writeText(str).then(() => { |
|
|
|
message.info('复制成功!'); |
|
|
|
}).catch(err => { |
|
|
|
message.info(err); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
const columns = useMemo<ColumnsType>(() => { |
|
|
|
return [ |
|
|
|
{ |
|
|
|
title: ( |
|
|
|
<> |
|
|
|
{t(`${i18nPrefix}.status.columns.status`, "状态")} |
|
|
|
<Tooltip title={t(`${i18nPrefix}.status.columns.statusTip`, "正确配置DNS解析后,域名验证会自动通过")}> |
|
|
|
<InfoCircleOutlined style={{ paddingInlineStart: 5 }} /> |
|
|
|
</Tooltip>{" "} |
|
|
|
</> |
|
|
|
<> |
|
|
|
{t(`${i18nPrefix}.status.columns.status`, "状态")} |
|
|
|
<Tooltip title={t(`${i18nPrefix}.status.columns.statusTip`, "正确配置DNS解析后,域名验证会自动通过")}> |
|
|
|
<InfoCircleOutlined style={{ paddingInlineStart: 5 }} /> |
|
|
|
</Tooltip>{" "} |
|
|
|
</> |
|
|
|
), |
|
|
|
dataIndex: "status", |
|
|
|
width: 100, |
|
|
@ -106,9 +114,9 @@ const StatusTable = (props: { value: string }) => { |
|
|
|
if (isVerifyFetching) { |
|
|
|
//0,等待 1,域名OK,2,域名分析错误,3:检测中 4:检测成功,匹配失败 5:检测失败,9:检测成功
|
|
|
|
return ( |
|
|
|
<span> |
|
|
|
<span> |
|
|
|
<LoadingOutlined style={{ paddingInlineEnd: 5 }} /> |
|
|
|
{t(`${i18nPrefix}.actions.dnsVerifyStatus.3`, "检测中")} |
|
|
|
{t(`${i18nPrefix}.actions.dnsVerifyStatus.3`, "检测中")} |
|
|
|
</span> |
|
|
|
); |
|
|
|
} |
|
|
@ -127,9 +135,9 @@ const StatusTable = (props: { value: string }) => { |
|
|
|
width: 150, |
|
|
|
render(text) { |
|
|
|
if (text) { |
|
|
|
return <span className={"color-green1"}>{text}</span>; |
|
|
|
return <span className={"color-yellow"}>{text}</span>; |
|
|
|
} |
|
|
|
return <span className={"color-yellow"}>未知</span>; |
|
|
|
return <span className={"color-red"}>未知</span>; |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
@ -137,6 +145,13 @@ const StatusTable = (props: { value: string }) => { |
|
|
|
title: t(`${i18nPrefix}.status.columns.domain`, "域名"), |
|
|
|
dataIndex: "dns_name", |
|
|
|
width: 200, |
|
|
|
render(text) { |
|
|
|
return ( |
|
|
|
<Button size="small" type="text" className={"color-green1"} icon={<CopyOutlined />} iconPosition={"end"} onClick={() => handleCopy(text)}> |
|
|
|
{text} |
|
|
|
</Button> |
|
|
|
); |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
//主机记录
|
|
|
@ -162,7 +177,11 @@ const StatusTable = (props: { value: string }) => { |
|
|
|
dataIndex: "record_value", |
|
|
|
width: 200, |
|
|
|
render: (text) => { |
|
|
|
return <Copy {...{ text: text, tooltips: t(`actions.clickCopy`) }} />; |
|
|
|
return ( |
|
|
|
<Button size="small" type="text" className={"color-green1"} icon={<CopyOutlined />} iconPosition={"end"} onClick={() => handleCopy(text)}> |
|
|
|
{t(`actions.clickCopy`)} |
|
|
|
</Button> |
|
|
|
); |
|
|
|
}, |
|
|
|
}, |
|
|
|
] as ColumnsType; |
|
|
@ -178,7 +197,7 @@ const StatusTable = (props: { value: string }) => { |
|
|
|
dns_name: "example.com", |
|
|
|
host: "example", |
|
|
|
type: "A", |
|
|
|
record_value: "192.168.1.1" |
|
|
|
record_value: "192.168.1.1", |
|
|
|
}, |
|
|
|
{ |
|
|
|
status: 3, |
|
|
@ -186,9 +205,9 @@ const StatusTable = (props: { value: string }) => { |
|
|
|
dns_name: "another.com", |
|
|
|
host: "another", |
|
|
|
type: "CNAME", |
|
|
|
record_value: "cname.another.com" |
|
|
|
} |
|
|
|
] |
|
|
|
record_value: "cname.another.com", |
|
|
|
}, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
setData(mockData); |
|
|
@ -217,24 +236,62 @@ const StatusTable = (props: { value: string }) => { |
|
|
|
}, [dnsVerifyStatus, isVerifyFetching]); |
|
|
|
|
|
|
|
return ( |
|
|
|
<> |
|
|
|
<div style={{ paddingBlock: 5, color: "#5a5a5a" }}> |
|
|
|
<Flex vertical={false} align={"center"}> |
|
|
|
<div>请您添加以下DNS解析记录</div> |
|
|
|
<Button type="link">参考文档</Button> |
|
|
|
</Flex> |
|
|
|
<div> 1. 只需要添加一次即可,添加后请勿删除记录。</div> |
|
|
|
<div> 2. 耐心等待1~2分钟。</div> |
|
|
|
</div> |
|
|
|
<Table |
|
|
|
columns={columns} |
|
|
|
dataSource={(data as any)?.dns_list} |
|
|
|
loading={isFetching} |
|
|
|
size={"small"} |
|
|
|
pagination={false} |
|
|
|
bordered={true} |
|
|
|
/> |
|
|
|
</> |
|
|
|
<> |
|
|
|
<div style={{ paddingBlock: 5, color: "#5a5a5a" }}> |
|
|
|
<Flex vertical={false} align={"center"}> |
|
|
|
<div>请您添加以下DNS解析记录</div> |
|
|
|
<Button type="link">参考文档</Button> |
|
|
|
</Flex> |
|
|
|
<div> 1. 只需要添加一次即可,添加后请勿删除记录。</div> |
|
|
|
<div> 2. 耐心等待1~2分钟。</div> |
|
|
|
</div> |
|
|
|
<Table |
|
|
|
columns={columns} |
|
|
|
dataSource={(data as any)?.dns_list} |
|
|
|
loading={isFetching} |
|
|
|
size={"small"} |
|
|
|
pagination={false} |
|
|
|
bordered={true} |
|
|
|
/> |
|
|
|
</> |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
const DomainsInput = (props: { setDomains; currentDomainMod; setCurrentDomainMod; currentStep }) => { |
|
|
|
return ( |
|
|
|
<Space direction="vertical" style={{ width: "100%" }}> |
|
|
|
<Radio.Group |
|
|
|
style={{ marginBottom: 8 }} |
|
|
|
value={props.currentDomainMod} |
|
|
|
onChange={(e) => props.setCurrentDomainMod(e.target.value)} |
|
|
|
> |
|
|
|
<Radio.Button value="single" disabled={props.currentStep !== 0}> |
|
|
|
单证书申请 |
|
|
|
</Radio.Button> |
|
|
|
<Radio.Button value="multiple" disabled={props.currentStep !== 0}> |
|
|
|
多证书申请 |
|
|
|
</Radio.Button> |
|
|
|
</Radio.Group> |
|
|
|
{props.currentDomainMod === "single" && ( |
|
|
|
<Input |
|
|
|
disabled={props.currentStep !== 0} |
|
|
|
placeholder="请输入域名,支持泛解析域名。如果为多个域名注册到一个证书,域名之间用<逗号(英文输入)>分割。如:a.com,*.b.com" |
|
|
|
/> |
|
|
|
)} |
|
|
|
{props.currentDomainMod === "multiple" && ( |
|
|
|
<Input.TextArea |
|
|
|
disabled={props.currentStep !== 0} |
|
|
|
rows={6} |
|
|
|
placeholder={`多个域名多个证书申请,用回车分隔。以下示例为6个域名申请3个证书,每行对应一个证书,支持泛解析域名;如:
|
|
|
|
*.a.baidu.com, *.baidu.com (两个域名一个证书) |
|
|
|
hello.alibaba.com,b.com,*.c.com (三个个域名一个证书) |
|
|
|
sss.ddd.com(单个域名一个证书)`}
|
|
|
|
onBlur={(e) => { |
|
|
|
props.setDomains(e.target.value); |
|
|
|
}} |
|
|
|
/> |
|
|
|
)} |
|
|
|
</Space> |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
@ -245,6 +302,8 @@ const Apply = () => { |
|
|
|
const [form] = Form.useForm(); |
|
|
|
const { mutate: saveOrUpdate, isPending: isSubmitting } = useAtomValue(saveOrUpdateCertAtom); |
|
|
|
const [domains, setDomains] = useAtom(domainsAtom); |
|
|
|
const [currentStep, setCurrentStep] = useState(0); |
|
|
|
const [currentDomainMod, setCurrentDomainMod] = useState<"single" | "multiple">("single"); |
|
|
|
const dnsVerifyOK = useAtomValue(dnsVerifyOKAtom); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
@ -256,103 +315,132 @@ const Apply = () => { |
|
|
|
}, [domains]); |
|
|
|
|
|
|
|
return ( |
|
|
|
<ListPageLayout |
|
|
|
childrenClassName={styles.applyContent} |
|
|
|
className={styles.applyContainer} |
|
|
|
title={t(`${i18nPrefix}.apply.title`, "证书申请")} |
|
|
|
> |
|
|
|
<Form |
|
|
|
form={form} |
|
|
|
{...{ |
|
|
|
labelCol: { span: 3 }, |
|
|
|
wrapperCol: { span: 16 }, |
|
|
|
}} |
|
|
|
onValuesChange={(values) => { |
|
|
|
// console.log('onValuesChange', values)
|
|
|
|
if (values.domains) { |
|
|
|
// setDomains(values.domains)
|
|
|
|
} |
|
|
|
}} |
|
|
|
onFinish={async (values) => { |
|
|
|
if (dnsVerifyOK) { |
|
|
|
saveOrUpdate(values); |
|
|
|
} |
|
|
|
}} |
|
|
|
<ListPageLayout |
|
|
|
childrenClassName={styles.applyContent} |
|
|
|
className={styles.applyContainer} |
|
|
|
title={t(`${i18nPrefix}.apply.title`, "证书申请")} |
|
|
|
> |
|
|
|
<div style={{ padding: "50px 50px 0 50px" }}> |
|
|
|
<Steps |
|
|
|
size="small" |
|
|
|
current={currentStep} |
|
|
|
items={[ |
|
|
|
{ |
|
|
|
title: "填写域名", |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "等待检测", |
|
|
|
}, |
|
|
|
{ |
|
|
|
title: "提交申请", |
|
|
|
}, |
|
|
|
]} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
<Form |
|
|
|
form={form} |
|
|
|
{...{ |
|
|
|
labelCol: { span: 3 }, |
|
|
|
wrapperCol: { span: 16 }, |
|
|
|
}} |
|
|
|
onValuesChange={(values) => { |
|
|
|
// console.log('onValuesChange', values)
|
|
|
|
if (values.domains) { |
|
|
|
// setDomains(values.domains)
|
|
|
|
} |
|
|
|
}} |
|
|
|
onFinish={async (values) => { |
|
|
|
if (dnsVerifyOK) { |
|
|
|
saveOrUpdate(values); |
|
|
|
} |
|
|
|
}} |
|
|
|
> |
|
|
|
{/* <Form.Item*/} |
|
|
|
{/* name={"domains"}*/} |
|
|
|
{/* label={t(`${i18nPrefix}.columns.quota`, "证书额度")}*/} |
|
|
|
{/* >*/} |
|
|
|
{/* <Flex vertical gap="small" style={{ width: 300 }}>*/} |
|
|
|
{/*<span>*/} |
|
|
|
{/* <span style={{ color: "#00762B" }}>{t(`${i18nPrefix}.apply.remaining`, "剩余5张")}</span>*/} |
|
|
|
{/* <span style={{ color: "#000000" }}>/ {t(`${i18nPrefix}.apply.total`, "共5张")}</span>*/} |
|
|
|
{/*</span>*/} |
|
|
|
{/* <Progress percent={30} strokeColor="#00762B" />*/} |
|
|
|
{/* </Flex>*/} |
|
|
|
{/* </Form.Item>*/} |
|
|
|
<Form.Item |
|
|
|
name={"domains"} |
|
|
|
label={t(`${i18nPrefix}.columns.domains`, "域名")} |
|
|
|
rules={[{ required: true, message: t(`${i18nPrefix}.columns.domains.required`, "请输入域名") }]} |
|
|
|
> |
|
|
|
<DomainsInput |
|
|
|
currentDomainMod={currentDomainMod} |
|
|
|
setCurrentDomainMod={setCurrentDomainMod} |
|
|
|
setDomains={setDomains} |
|
|
|
currentStep={currentStep} |
|
|
|
/> |
|
|
|
</Form.Item> |
|
|
|
{currentStep !== 0 && ( |
|
|
|
<> |
|
|
|
<Form.Item |
|
|
|
label={t(`${i18nPrefix}.columns.type`, "域名验证")} |
|
|
|
rules={[{ required: true, message: t(`${i18nPrefix}.columns.type`, "域名验证没有通过") }]} |
|
|
|
> |
|
|
|
{/* <Form.Item*/} |
|
|
|
{/* name={"domains"}*/} |
|
|
|
{/* label={t(`${i18nPrefix}.columns.quota`, "证书额度")}*/} |
|
|
|
{/* >*/} |
|
|
|
{/* <Flex vertical gap="small" style={{ width: 300 }}>*/} |
|
|
|
{/*<span>*/} |
|
|
|
{/* <span style={{ color: "#00762B" }}>{t(`${i18nPrefix}.apply.remaining`, "剩余5张")}</span>*/} |
|
|
|
{/* <span style={{ color: "#000000" }}>/ {t(`${i18nPrefix}.apply.total`, "共5张")}</span>*/} |
|
|
|
{/*</span>*/} |
|
|
|
{/* <Progress percent={30} strokeColor="#00762B" />*/} |
|
|
|
{/* </Flex>*/} |
|
|
|
{/* </Form.Item>*/} |
|
|
|
<Form.Item |
|
|
|
name={"domains"} |
|
|
|
label={t(`${i18nPrefix}.columns.domains`, "域名")} |
|
|
|
rules={[{ required: true, message: t(`${i18nPrefix}.columns.domains.required`, "请输入域名") }]} |
|
|
|
> |
|
|
|
<Input.TextArea |
|
|
|
rows={5} |
|
|
|
placeholder={`请输入域名,每行一个,支持泛解析域名;如:
|
|
|
|
*.google.com |
|
|
|
*.a.baidu.com |
|
|
|
hello.alibaba.com`}
|
|
|
|
onBlur={(e) => { |
|
|
|
setDomains(e.target.value); |
|
|
|
}} |
|
|
|
/> |
|
|
|
</Form.Item> |
|
|
|
<Form.Item |
|
|
|
label={t(`${i18nPrefix}.columns.type`, "域名验证")} |
|
|
|
rules={[{ required: true, message: t(`${i18nPrefix}.columns.type`, "域名验证没有通过") }]} |
|
|
|
> |
|
|
|
<StatusTable value={domains} /> |
|
|
|
</Form.Item> |
|
|
|
<Form.Item |
|
|
|
name={"brand"} |
|
|
|
label={t(`${i18nPrefix}.columns.brand`, "证书品牌")} |
|
|
|
rules={[ |
|
|
|
{ |
|
|
|
required: true, |
|
|
|
message: t(`${i18nPrefix}.columns.brand.required`, "请选择证书品牌"), |
|
|
|
}, |
|
|
|
]} |
|
|
|
> |
|
|
|
<BrandSelect /> |
|
|
|
</Form.Item> |
|
|
|
<Form.Item |
|
|
|
name={"algorithm"} |
|
|
|
label={t(`${i18nPrefix}.columns.algorithm`, "加密方式")} |
|
|
|
rules={[ |
|
|
|
{ |
|
|
|
required: true, |
|
|
|
message: t(`${i18nPrefix}.columns.algorithm.required`, "请选择加密方式"), |
|
|
|
}, |
|
|
|
]} |
|
|
|
> |
|
|
|
<Select style={{ width: 120 }} options={algorithmTypes} /> |
|
|
|
</Form.Item> |
|
|
|
<Form.Item name={"remark"} label={t(`${i18nPrefix}.columns.remark`, "备注 ")}> |
|
|
|
<Input style={{ width: 400 }} /> |
|
|
|
</Form.Item> |
|
|
|
<Form.Item label={" "} colon={false}> |
|
|
|
<Space> |
|
|
|
<Button disabled={!dnsVerifyOK || isSubmitting} htmlType={"submit"}> |
|
|
|
{t(`${i18nPrefix}.apply.prev`, "上一步")} |
|
|
|
</Button> |
|
|
|
<Button type={"primary"} disabled={!dnsVerifyOK || isSubmitting} htmlType={"submit"}> |
|
|
|
{t(`${i18nPrefix}.apply.submit`, "提交申请")} |
|
|
|
</Button> |
|
|
|
</Space> |
|
|
|
</Form.Item> |
|
|
|
</Form> |
|
|
|
</ListPageLayout> |
|
|
|
<StatusTable value={domains} /> |
|
|
|
</Form.Item> |
|
|
|
|
|
|
|
<Form.Item |
|
|
|
name={"brand"} |
|
|
|
label={t(`${i18nPrefix}.columns.brand`, "证书品牌")} |
|
|
|
rules={[ |
|
|
|
{ |
|
|
|
required: true, |
|
|
|
message: t(`${i18nPrefix}.columns.brand.required`, "请选择证书品牌"), |
|
|
|
}, |
|
|
|
]} |
|
|
|
> |
|
|
|
<BrandSelect value="Google" /> |
|
|
|
</Form.Item> |
|
|
|
<Form.Item |
|
|
|
name={"algorithm"} |
|
|
|
label={t(`${i18nPrefix}.columns.algorithm`, "加密方式")} |
|
|
|
rules={[ |
|
|
|
{ |
|
|
|
required: true, |
|
|
|
message: t(`${i18nPrefix}.columns.algorithm.required`, "请选择加密方式"), |
|
|
|
}, |
|
|
|
]} |
|
|
|
> |
|
|
|
<Select style={{ width: 120 }} options={algorithmTypes} /> |
|
|
|
</Form.Item> |
|
|
|
<Form.Item name={"remark"} label={t(`${i18nPrefix}.columns.remark`, "备注 ")}> |
|
|
|
<Input style={{ width: 400 }} /> |
|
|
|
</Form.Item> |
|
|
|
</> |
|
|
|
)} |
|
|
|
<Form.Item label={" "} colon={false}> |
|
|
|
<Space> |
|
|
|
{currentStep !== 0 && ( |
|
|
|
<Button type="primary" onClick={() => setCurrentStep(currentStep - 1)} htmlType={"submit"}> |
|
|
|
{t(`${i18nPrefix}.apply.prev`, "上一步")} |
|
|
|
</Button> |
|
|
|
)} |
|
|
|
|
|
|
|
{currentStep === 0 && ( |
|
|
|
<Button type="primary" onClick={() => setCurrentStep(currentStep + 1)} htmlType={"submit"}> |
|
|
|
{t(`${i18nPrefix}.apply.next`, "下一步")} |
|
|
|
</Button> |
|
|
|
)} |
|
|
|
|
|
|
|
{currentStep !== 0 && ( |
|
|
|
<Button type="primary" htmlType={"submit"} disabled={currentStep === 1}> |
|
|
|
{t(`${i18nPrefix}.apply.submit`, "提交申请")} |
|
|
|
</Button> |
|
|
|
)} |
|
|
|
</Space> |
|
|
|
</Form.Item> |
|
|
|
</Form> |
|
|
|
</ListPageLayout> |
|
|
|
); |
|
|
|
}; |
|
|
|
|
|
|
|
export default Apply; |
|
|
|
export default Apply; |