完善页面功能

This commit is contained in:
WenC 2024-03-26 21:09:41 +08:00
parent dbb8f3c924
commit 04d1905906
12 changed files with 673 additions and 92 deletions

View File

@ -1,20 +1,46 @@
import Head from './layout/head/Head.tsx'; import Head from './layout/head/Head.tsx';
import Body from './layout/body/Body.tsx'; import Body from './layout/body/Body.tsx';
import Foot from './layout/foot/Foot.tsx'; import Foot from './layout/foot/Foot.tsx';
import {GlobalContext, GlobalData} from "./context/GlobalContext.ts"; import {
GlobalContext,
GlobalData,
GlobalDataAction,
GlobalDataActionType,
GlobalDispatchContext
} from "./context/GlobalContext.ts";
import {Reducer, useReducer} from "react";
const App: React.FC = () => { const App: React.FC = () => {
const globalDataReducer = (state: GlobalData, action: GlobalDataAction) => {
const globalData: GlobalData = { if (action.type == GlobalDataActionType.REFRESH_SELF) {
if(action.user) {
state.user.balance = action.user.balance;
state.user.nickname = action.user.nickname;
state.user.username = action.user.username;
state.user.hasUserInfo = action.user.hasUserInfo;
}
}
return {
...state
}
} }
const [globalData, dispatch] = useReducer<Reducer<GlobalData, GlobalDataAction>>(globalDataReducer, {
user: {
balance: '0',
username: '',
nickname: '',
hasUserInfo: false
}
});
return ( return (
<> <>
<GlobalContext.Provider value={globalData}> <GlobalContext.Provider value={globalData}>
<Head/> <GlobalDispatchContext.Provider value={dispatch}>
<Body/> <Head/>
<Foot/> <Body/>
<Foot/>
</GlobalDispatchContext.Provider>
</GlobalContext.Provider> </GlobalContext.Provider>
</> </>
); );

View File

@ -1,15 +1,16 @@
import './balance-head.css' import './balance-head.css'
import {useContext} from "react";
import {GlobalContext} from "../../context/GlobalContext.ts";
export default function BalanceHead() { export default function BalanceHead() {
const globalContext = useContext(GlobalContext);
const handleClick = () => {
console.log('查看余额')
}
return ( return (
<div className="head-item balance-head"> <div className="head-item balance-head">
<span className="label"></span> <span className="label"></span>
<span className="balance" onClick={handleClick}>800</span> <span className="balance" onClick={() => {
console.log('查看余额')
}}>{globalContext.user.balance}</span>
</div> </div>
) )
} }

View File

@ -1,48 +1,51 @@
import './card-proj.css'; import './card-proj.css';
import { import {
CheckOutlined,
ClockCircleOutlined,
CloseCircleOutlined,
CreditCardOutlined,
DownloadOutlined, DownloadOutlined,
EditOutlined, EditOutlined,
EyeOutlined, EyeOutlined,
FolderOutlined, FolderOutlined,
LoadingOutlined,
SearchOutlined, SearchOutlined,
SettingOutlined, SettingOutlined,
ClockCircleOutlined, WarningOutlined
LoadingOutlined,
CheckOutlined,
WarningOutlined,
CloseCircleOutlined,
CreditCardOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import {Button, ConfigProvider, Tag} from 'antd'; import {Button, ConfigProvider, Tag} from 'antd';
import {GenerateStatus, IProj, PayStatus} from "../../interfaces/proj/IProj.ts"; import {GenerateStatus, IProj, PayStatus} from "../../interfaces/proj/IProj.ts";
import {useNavigate} from "react-router-dom";
import {Axios} from "../../util/AjaxUtils.ts";
export default function CardProj(props: { item: IProj }) { export default function CardProj(props: { item: IProj }) {
const nav = useNavigate();
const data = props.item; const data = props.item;
/** /**
* *
*/ */
const renderGenerateStatus = () => { const renderGenerateStatus = () => {
if (data.generateStatus == GenerateStatus.PENDING) { if (data.generate.generateStatus == GenerateStatus.PENDING) {
return <Tag color="cyan"><ClockCircleOutlined/> </Tag> return <Tag color="cyan"><ClockCircleOutlined/> </Tag>
} }
if (data.generateStatus == GenerateStatus.GENERATING) { if (data.generate.generateStatus == GenerateStatus.GENERATING) {
return <Tag color="magenta"><LoadingOutlined/> </Tag> return <Tag color="magenta"><LoadingOutlined/> </Tag>
} }
if (data.generateStatus == GenerateStatus.SUCCESS) { if (data.generate.generateStatus == GenerateStatus.SUCCESS) {
return <Tag color="green"><CheckOutlined/> </Tag> return <Tag color="green"><CheckOutlined/> </Tag>
} }
if (data.generateStatus == GenerateStatus.FAILED) { if (data.generate.generateStatus == GenerateStatus.FAILED) {
return <Tag color="red"><WarningOutlined/> </Tag> return <Tag color="red"><WarningOutlined/> </Tag>
} }
if (data.generateStatus == GenerateStatus.NONE) { if (data.generate.generateStatus == GenerateStatus.NONE) {
return <Tag color="cyan"></Tag> return <Tag color="cyan"></Tag>
} }
return <Tag color="red"><CloseCircleOutlined/> </Tag> return <Tag color="red"><CloseCircleOutlined/> </Tag>
} }
const renderOption = () => { const renderOption = () => {
if(data.payStatus == PayStatus.UNPAID) { if(data.pay.payStatus == PayStatus.UNPAID) {
return ( return (
<> <>
<div className="option"> <div className="option">
@ -54,17 +57,44 @@ export default function CardProj(props: { item: IProj }) {
return ( return (
<> <>
<div className="option"> <div className="option">
<Button size="small" type="text"><SettingOutlined/> </Button> <Button size="small" type="text" onClick={() => {
<Button size="small" type="text"><SettingOutlined/> (0)</Button> if(data.generate.generateStatus == GenerateStatus.SUCCESS) {
<Button size="small" type="text"><SettingOutlined/> (0)</Button> nav(`/proj-edit/config-loginpage-show/${data.projId}`)
} else {
nav(`/proj-edit/config-loginpage/${data.projId}`)
}
}}><SettingOutlined/> </Button>
<Button size="small" type="text" onClick={() => {
if(data.generate.generateStatus == GenerateStatus.SUCCESS) {
nav(`/proj-edit/config-mod-list-show/${data.projId}`)
} else {
nav(`/proj-edit/config-mod-list/${data.projId}`)
}
}}><SettingOutlined/> (0)</Button>
<Button size="small" type="text" onClick={() => {
if(data.generate.generateStatus == GenerateStatus.SUCCESS) {
nav(`/proj-edit/config-menu-list-show/${data.projId}`)
} else {
nav(`/proj-edit/config-menu-list/${data.projId}`)
}
}}><SettingOutlined/> (0)</Button>
</div> </div>
{ {
data.generateStatus == GenerateStatus.SUCCESS ? ( data.generate.generateStatus == GenerateStatus.SUCCESS ? (
<div className="option"> <div className="option">
<Button size="small" type="text"><DownloadOutlined/> </Button> <Button size="small" type="text" onClick={() => {
<Button size="small" type="text"><DownloadOutlined/> </Button> window.open(`${Axios.defaults?.baseURL}/route/proj/download/apply/${data.projId}`)
<Button size="small" type="text"><DownloadOutlined/> </Button> }}><DownloadOutlined/> </Button>
<Button size="small" type="text"><DownloadOutlined/> </Button> <Button size="small" type="text" onClick={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/manual/${data.projId}`)
}}><DownloadOutlined/> </Button>
<Button size="small" type="text" onClick={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/code-zip/${data.projId}`)
}}><DownloadOutlined/> </Button>
<Button size="small" type="text" onClick={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/code/${data.projId}`)
}}><DownloadOutlined/> </Button>
</div> </div>
) : <></> ) : <></>
} }
@ -88,22 +118,33 @@ export default function CardProj(props: { item: IProj }) {
<div className="body"> <div className="body">
<div className="line"> <div className="line">
<div className="left"> <div className="left">
<span>{data.payment / 100}</span> <span>{data.pay.payment / 100}</span>
</div> </div>
<div className="right"> <div className="right">
<span> {
<EditOutlined/> data.generate.generateStatus == GenerateStatus.SUCCESS ? (
<a href="/#"></a> <span>
</span> <SearchOutlined/>
<span> <a href="/#" onClick={(e) => {
<SearchOutlined/> e.preventDefault();
<a href="/#"></a> nav(`/proj-edit/${data.projId}`)
</span> }}></a>
</span>
) : (
<span>
<EditOutlined/>
<a href="/#" onClick={(e) => {
e.preventDefault();
nav(`/proj-edit/${data.projId}`)
}}></a>
</span>
)
}
<span> <span>
<EyeOutlined/> <EyeOutlined/>
<a href="/#" onClick={(e) => { <a href="/#" onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
window.open(data.previewUrl, '_blank') window.open(`${Axios.defaults?.baseURL}/${data.previewUrl}`, '_blank')
}}></a> }}></a>
</span> </span>
</div> </div>

View File

@ -5,12 +5,21 @@ export default function CardProjDownload(props: IProjDownload) {
return ( return (
<div className="card-proj-download"> <div className="card-proj-download">
<div className="title">{props.title}</div> <div className="title">{props.title}</div>
<div className="desc"></div> <div className="desc">{props.desc}</div>
<div className="option"> <div className="option">
<a href="/#" className="edit" onClick={(e) => { {
e.preventDefault(); props.canBtnClick ? (
props.handleDownload(); <a href="/#" className="edit" onClick={(e) => {
}}></a> e.preventDefault();
props.handleDownload();
}}></a>
) : (
<a href="/#" className="edit" style={{color: 'var(--color-border)'}} onClick={(e) => {
e.preventDefault();
}}></a>
)
}
</div> </div>
</div> </div>
) )

View File

@ -1,8 +1,33 @@
import {createContext} from "react"; import {createContext, Dispatch} from "react";
export interface GlobalData { export enum GlobalDataActionType {
REFRESH_SELF
} }
const Data: GlobalData = {} export interface User {
balance: string;
nickname: string;
username: string;
hasUserInfo: boolean;
}
export const GlobalContext = createContext<GlobalData>(Data); export interface GlobalData {
user: User;
}
export interface GlobalDataAction {
type: number;
user?: User;
}
export const GlobalContext = createContext<GlobalData>({
user: {
balance: '0',
nickname: '',
username: '',
hasUserInfo: false
}
});
export const GlobalDispatchContext = createContext<Dispatch<GlobalDataAction>>(() => {});

View File

@ -32,6 +32,7 @@ export interface IProjResult {
export interface IProjDownload { export interface IProjDownload {
title: string; title: string;
desc: string; desc: string;
canBtnClick?: boolean;
handleDownload(): void; handleDownload(): void;
} }

View File

@ -47,18 +47,30 @@ export interface IProjCharge {
} }
} }
export interface IProjGenerate {
generateStatus: GenerateStatus;
}
export interface IProjPay {
charge: string;
gmtPay: string;
payStatus: PayStatus;
payment: number;
chargeAdditionals: string;
}
export interface IProj { export interface IProj {
projId: string, projId: string,
projName: string; projName: string;
projContext: string; projContext: string;
projCodeType: ProjCodeType, projCodeType: ProjCodeType;
payStatus: PayStatus, projStyleType: ProjStyleType;
payment: number, previewUrl: string;
projStyleType: ProjStyleType, gmtCreate: string;
previewUrl: string,
gmtCreate: string, generate: IProjGenerate;
generateStatus: GenerateStatus pay: IProjPay;
} }

View File

@ -1,11 +1,41 @@
import './head.css' import './head.css'
import BalanceHead from '../../components/balance/BalanceHead.tsx'; import BalanceHead from '../../components/balance/BalanceHead.tsx';
import RechargeHead from '../../components/recharge/RechargeHead.tsx'; import RechargeHead from '../../components/recharge/RechargeHead.tsx';
import MessageHead from '../../components/message/MessageHead.tsx'; import {Divider, Dropdown, MenuProps, message, Modal, Space, Spin} from "antd";
import {Divider, Dropdown, MenuProps, Space} from "antd";
import {DownOutlined, UserOutlined, KeyOutlined, LogoutOutlined} from "@ant-design/icons"; import {DownOutlined, UserOutlined, KeyOutlined, LogoutOutlined} from "@ant-design/icons";
import {useContext, useEffect, useState} from "react";
import {get, put} from "../../util/AjaxUtils.ts";
import {GlobalContext, GlobalDataActionType, GlobalDispatchContext} from "../../context/GlobalContext.ts";
import UserEdit from "../../route/user/UserEdit.tsx";
export default function Head() { export default function Head() {
const globalContext = useContext(GlobalContext);
const globalDispatchContext = useContext(GlobalDispatchContext);
const [messageApi, contextHolder] = message.useMessage();
const [modal, modalHolder] = Modal.useModal();
const [loading, setLoading] = useState<boolean>(false);
const [isSelfModalOpen, setIsSelfModalOpen] = useState(false);
useEffect(() => {
get({
messageApi,
url: '/api/user-info/get-user-self',
onSuccess({data}) {
globalDispatchContext({
type: GlobalDataActionType.REFRESH_SELF,
user: {
balance: (Math.floor(data.accountMoney) / 100).toFixed(2),
nickname: data.nickname,
username: data.username,
hasUserInfo: data.hasUserInfo,
}
})
if(!data.hasUserInfo) {
setIsSelfModalOpen(true);
}
}
})
}, [globalContext.user]);
const items: MenuProps['items'] = [ const items: MenuProps['items'] = [
{ {
@ -16,6 +46,9 @@ export default function Head() {
<span className="title"></span> <span className="title"></span>
</div> </div>
), ),
onClick: () => {
setIsSelfModalOpen(true);
}
}, },
{ {
key: 'changePass', key: 'changePass',
@ -38,29 +71,76 @@ export default function Head() {
] ]
return ( return (
<div className="head"> <>
<div className="center"> <div className="head">
<div className="left"> <div className="center">
<span className="sys-title">AI引擎软著</span> <div className="left">
<Divider type="vertical"/> <span className="sys-title">AI引擎软著</span>
<span className="sys-title-sub"></span> <Divider type="vertical"/>
</div> <span className="sys-title-sub"></span>
<div className="right"> </div>
<BalanceHead/> <div className="right">
<RechargeHead/> <BalanceHead/>
<MessageHead/> <RechargeHead/>
<div style={{display: 'flex', alignContent: 'center', padding: '0 10px', cursor: 'pointer'}}> {/*<MessageHead/>*/}
<Dropdown menu={{ <div style={{display: 'flex', alignContent: 'center', padding: '0 10px', cursor: 'pointer'}}>
items: items <Dropdown menu={{
}}> items: items
<Space> }}>
18888888 <Space>
<DownOutlined/> {globalContext.user.nickname}
</Space> <DownOutlined/>
</Dropdown> </Space>
</Dropdown>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <Modal open={isSelfModalOpen}
title="个人信息"
footer={false}
onCancel={() => {
if(!globalContext.user.hasUserInfo) {
messageApi.info('请完善个人信息');
return;
}
setIsSelfModalOpen(false)
}} >
<UserEdit handleConfirm={(data) => {
modal.confirm({
title: 'Confirm',
content: '确定保存吗?',
okText: '确认',
cancelText: '取消',
okButtonProps: {
style: {
backgroundColor: 'var(--color-primary)'
}
},
onOk: () => {
setIsSelfModalOpen(false);
put({
messageApi,
url: '/api/user-info/update-self',
body: data,
onBefore() {
setLoading(true);
},
onSuccess() {
messageApi.success('修改成功');
},
onFinally() {
setLoading(false);
}
})
console.log(data);
}
});
}}/>
</Modal>
<Spin tip="正在提交..." spinning={loading} fullscreen/>
{contextHolder}
{modalHolder}
</>
) )
} }

View File

@ -320,30 +320,30 @@ export default function ProjEdit() {
descTitle="资料下载"> descTitle="资料下载">
<CardProjDownload title="申请表" <CardProjDownload title="申请表"
desc="点击下载申请表" desc="点击下载申请表"
canBtnClick={generateStatus == GenerateStatus.SUCCESS}
handleDownload={() => { handleDownload={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/apply/${pathParams.projId}`) window.open(`${Axios.defaults?.baseURL}/route/proj/download/apply/${pathParams.projId}`)
console.log('下载')
}} }}
/> />
<CardProjDownload title="操作手册" <CardProjDownload title="操作手册"
desc="点击下载操作手册" desc="点击下载操作手册"
canBtnClick={generateStatus == GenerateStatus.SUCCESS}
handleDownload={() => { handleDownload={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/manual/${pathParams.projId}`) window.open(`${Axios.defaults?.baseURL}/route/proj/download/manual/${pathParams.projId}`)
console.log('下载')
}} }}
/> />
<CardProjDownload title="代码压缩包" <CardProjDownload title="代码压缩包"
desc="点击下载代码压缩包" desc="点击下载代码压缩包"
canBtnClick={generateStatus == GenerateStatus.SUCCESS}
handleDownload={() => { handleDownload={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/code-zip/${pathParams.projId}`) window.open(`${Axios.defaults?.baseURL}/route/proj/download/code-zip/${pathParams.projId}`)
console.log('下载')
}} }}
/> />
<CardProjDownload title="代码文档" <CardProjDownload title="代码文档"
desc="点击下载代码文档" desc="点击下载代码文档"
canBtnClick={generateStatus == GenerateStatus.SUCCESS}
handleDownload={() => { handleDownload={() => {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/code/${pathParams.projId}`) window.open(`${Axios.defaults?.baseURL}/route/proj/download/code/${pathParams.projId}`)
console.log('下载')
}} }}
/> />
<CardProjJump title="跳转" <CardProjJump title="跳转"

View File

@ -84,7 +84,7 @@ export default function ProjConfigLoginpage() {
form.setFieldValue('adminPassword', data.adminPassword); form.setFieldValue('adminPassword', data.adminPassword);
if (data.logo) { if (data.logo) {
const url = downloadUrl(data.logo); const url = downloadUrl(data.logo);
logoImgArray.push({ logoImgArray.splice(0, 1, {
uid: data.logo, uid: data.logo,
name: 'logo.png', name: 'logo.png',
status: 'done', status: 'done',
@ -97,7 +97,7 @@ export default function ProjConfigLoginpage() {
} }
if (data.bgImgs) { if (data.bgImgs) {
const url = downloadUrl(data.bgImgs); const url = downloadUrl(data.bgImgs);
bgImgArray.push({ bgImgArray.splice(0, 1, {
uid: data.bgImgs, uid: data.bgImgs,
name: 'bg.png', name: 'bg.png',
status: 'done', status: 'done',
@ -201,13 +201,13 @@ export default function ProjConfigLoginpage() {
setLoading(false); setLoading(false);
const fileId = info.file.response.data.fileId; const fileId = info.file.response.data.fileId;
const url = downloadUrl(fileId); const url = downloadUrl(fileId);
logoImgArray[0] = { logoImgArray.splice(0, 1, {
uid: info.file.response.data.fileId, uid: info.file.response.data.fileId,
name: 'logo.png', name: 'logo.png',
status: 'done', status: 'done',
url: url, url: url,
thumbUrl: url, thumbUrl: url,
} })
setLogoImgArray([ setLogoImgArray([
...logoImgArray ...logoImgArray
]) ])
@ -246,13 +246,13 @@ export default function ProjConfigLoginpage() {
setLoading(false); setLoading(false);
const fileId = info.file.response.data.fileId; const fileId = info.file.response.data.fileId;
const url = downloadUrl(fileId); const url = downloadUrl(fileId);
bgImgArray[0] = { bgImgArray.splice(0, 1, {
uid: info.file.response.data.fileId, uid: info.file.response.data.fileId,
name: 'bg.png', name: 'bg.png',
status: 'done', status: 'done',
url: url, url: url,
thumbUrl: url, thumbUrl: url,
} })
setBgImgArray([ setBgImgArray([
...bgImgArray ...bgImgArray
]) ])

View File

@ -34,7 +34,7 @@ export default function ProjEditStep2() {
form.setFieldsValue({ form.setFieldsValue({
projSubName: data.projSubName, projSubName: data.projSubName,
projVersion: data.projVersion, projVersion: data.projVersion,
projDevCompleteDate: dayjs(data.projDevCompleteDate, 'YYYY-MM-DD'), projDevCompleteDate: data.projDevCompleteDate ? dayjs(data.projDevCompleteDate, 'YYYY-MM-DD') : '',
companyName: data.companyName, companyName: data.companyName,
companyNameEn: data.companyNameEn, companyNameEn: data.companyNameEn,
}) })

386
src/route/user/UserEdit.tsx Normal file
View File

@ -0,0 +1,386 @@
import {
Button,
Col,
DatePicker, Flex,
Form,
GetProp,
Input,
message,
Radio,
Row,
Spin,
Upload,
UploadFile,
UploadProps
} from "antd";
import {DevUserId, downloadUrl, get, uploadImageUrl} from "../../util/AjaxUtils.ts";
import {useEffect, useState} from "react";
import locale from "antd/es/date-picker/locale/zh_CN";
import dayjs, {Dayjs} from "dayjs";
type FormDataType = {
userId: string;
userInfoId: string;
userInfoType: string;
userInfoName: string;
idCardType: string;
idCardNumber: string;
idCardFront: string;
idCardBack: string;
idCardStartDate: Dayjs;
idCardEndDate: Dayjs;
legalPerson: string;
establishDate: Dayjs;
contactAddress: string;
contactPhone: string;
}
type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];
const dateFormat = 'YYYY年MM月DD日';
export interface IUserEditProps {
handleConfirm(data: FormDataType): void;
}
export default function UserEdit(props: IUserEditProps) {
const [messageApi, contextHolder] = message.useMessage();
const [form] = Form.useForm<FormDataType>();
const [userInfoType, setUserInfoType] = useState('PERSONAL');
const [idCardFrontImgArray, setIdCardFrontImgArray] = useState<UploadFile[]>([]);
const [idCardBackImgArray, setIdCardBackImgArray] = useState<UploadFile[]>([]);
const [loading, setLoading] = useState(false);
const beforeUpload = (file: FileType) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('只能上传 JPG/PNG 格式文件!');
}
return isJpgOrPng;
};
useEffect(() => {
get({
messageApi,
url: 'api/user-info/get-self',
onSuccess({data}) {
form.setFieldsValue({
userId: data.userId,
userInfoId: data.userInfoId,
userInfoName: data.userInfoName,
userInfoType: data.userInfoType,
contactAddress: data.contactAddress,
contactPhone: data.contactPhone,
establishDate: data.establishDate ? dayjs(data.establishDate, 'YYYY-MM-DD') : '',
idCardNumber: data.idCardNumber,
idCardFront: data.idCardFront,
idCardStartDate: data.idCardStartDate ? dayjs(data.idCardStartDate, 'YYYY-MM-DD') : '',
idCardBack: data.idCardBack,
idCardEndDate: data.idCardEndDate ? dayjs(data.idCardEndDate, 'YYYY-MM-DD') : '',
idCardType: data.idCardType,
legalPerson: data.legalPerson,
})
if (data.idCardFront) {
const url = downloadUrl(data.idCardFront);
idCardFrontImgArray.splice(0, 1, {
uid: data.idCardFront,
name: 'front.png',
status: 'done',
url: url,
thumbUrl: url,
})
setIdCardFrontImgArray([
...idCardFrontImgArray,
])
}
if (data.idCardBack) {
const url = downloadUrl(data.idCardBack);
idCardBackImgArray.splice(0, 1, {
uid: data.idCardBack,
name: 'back.png',
status: 'done',
url: url,
thumbUrl: url,
})
setIdCardBackImgArray([
...idCardBackImgArray,
])
}
setUserInfoType(data.userInfoType);
}
})
}, [form])
return (
<>
<Form
layout="vertical"
form={form}
onFinish={() => {
props.handleConfirm({
userId: form.getFieldValue('userId'),
userInfoId: form.getFieldValue('userInfoId'),
userInfoName: form.getFieldValue('userInfoName'),
userInfoType: form.getFieldValue('userInfoType'),
contactAddress: form.getFieldValue('contactAddress'),
contactPhone: form.getFieldValue('contactPhone'),
establishDate: form.getFieldValue('establishDate') ? form.getFieldValue('establishDate').format(dateFormat) : '',
idCardBack: form.getFieldValue('idCardBack'),
idCardEndDate: form.getFieldValue('idCardEndDate') ? form.getFieldValue('idCardEndDate').format(dateFormat) : '',
idCardFront: form.getFieldValue('idCardFront'),
idCardNumber: form.getFieldValue('idCardNumber'),
idCardStartDate: form.getFieldValue('idCardStartDate') ? form.getFieldValue('idCardStartDate').format(dateFormat) : '',
idCardType: form.getFieldValue('idCardType'),
legalPerson: form.getFieldValue('legalPerson'),
});
}}
>
<Form.Item label="类型"
name="userInfoType"
rules={[{required: true, message: '请选择类型'}]}
>
<Radio.Group onChange={(e) => {
setUserInfoType(e.target.value);
if (e.target.value === 'PERSONAL') {
form.setFieldValue('idCardType', 'ID_CARD');
}
if (e.target.value === 'ENTERPRISE') {
form.setFieldValue('idCardType', 'ORGANIZATION_CODE');
}
}}>
<Radio.Button value="PERSONAL"></Radio.Button>
<Radio.Button value="ENTERPRISE"></Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item label="名称"
name="userInfoName"
rules={[{required: true, message: '请输入名称'}]}
>
<Input placeholder="请输入名称"/>
</Form.Item>
{
userInfoType == 'PERSONAL' ? (
<Form.Item label="证件类型"
name="idCardType"
rules={[{required: true, message: '请选择证件类型'}]}
>
<Radio.Group>
<Radio.Button value="ID_CARD"></Radio.Button>
</Radio.Group>
</Form.Item>
) : <></>
}
{
userInfoType == 'ENTERPRISE' ? (
<Form.Item label="证件类型"
name="idCardType"
rules={[{required: true, message: '请选择证件类型'}]}
>
<Radio.Group>
<Radio.Button value="ORGANIZATION_CODE"></Radio.Button>
</Radio.Group>
</Form.Item>
) : <></>
}
<Form.Item label="证件号"
name="idCardNumber"
rules={[{required: true, message: '请输入证件号'}]}
>
<Input placeholder="请输入证件号"/>
</Form.Item>
<Row gutter={15}>
<Col span={12}>
<Form.Item label="证件照正面"
name="idCardFront"
rules={[{required: true, message: '请上传证件照正面'}]}
>
<Upload
name="image"
listType="picture"
maxCount={1}
defaultFileList={idCardFrontImgArray}
action={uploadImageUrl()}
headers={{'X-USER-ID': DevUserId}}
beforeUpload={beforeUpload}
onChange={(info) => {
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') {
setLoading(false);
const fileId = info.file.response.data.fileId;
const url = downloadUrl(fileId);
idCardFrontImgArray[0] = {
uid: info.file.response.data.fileId,
name: 'bg.png',
status: 'done',
url: url,
thumbUrl: url,
}
setIdCardFrontImgArray([
...idCardFrontImgArray
])
form.setFieldValue('idCardFront', fileId);
return;
}
}}
onRemove={() => {
idCardFrontImgArray.splice(0)
setIdCardFrontImgArray([
...idCardFrontImgArray
])
}}
>
<Button size="small" type="primary"
style={{backgroundColor: 'var(--color-primary)'}}
disabled={idCardFrontImgArray.length > 0}></Button>
</Upload>
</Form.Item>
</Col>
{
userInfoType == 'PERSONAL' ? (
<Col span={12}>
<Form.Item label="证件照反面"
name="idCardBack"
rules={[{required: true, message: '请上传证件照反面'}]}
>
<Upload
name="image"
listType="picture"
maxCount={1}
defaultFileList={idCardBackImgArray}
action={uploadImageUrl()}
headers={{'X-USER-ID': DevUserId}}
beforeUpload={beforeUpload}
onChange={(info) => {
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') {
setLoading(false);
const fileId = info.file.response.data.fileId;
const url = downloadUrl(fileId);
idCardBackImgArray[0] = {
uid: info.file.response.data.fileId,
name: 'bg.png',
status: 'done',
url: url,
thumbUrl: url,
}
setIdCardBackImgArray([
...idCardBackImgArray
])
form.setFieldValue('idCardBack', fileId);
return;
}
}}
onRemove={() => {
idCardBackImgArray.splice(0)
setIdCardBackImgArray([
...idCardBackImgArray
])
}}
>
<Button size="small" type="primary"
style={{backgroundColor: 'var(--color-primary)'}}
disabled={idCardBackImgArray.length > 0}></Button>
</Upload>
</Form.Item>
</Col>
) : <></>
}
</Row>
<Row gutter={15}>
<Col span={12}>
<Form.Item<FormDataType>
label="证件开始时间"
name="idCardStartDate"
rules={[{required: true, message: '请选择证件开始时间'}]}
>
<DatePicker placeholder="证件开始时间"
format={dateFormat}
locale={locale}
style={{width: '100%'}}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item<FormDataType>
label="证件结束时间"
name="idCardEndDate"
rules={[{required: true, message: '请选择证件结束时间'}]}
>
<DatePicker placeholder="证件结束时间"
format={dateFormat}
locale={locale}
style={{width: '100%'}}
/>
</Form.Item>
</Col>
</Row>
{
userInfoType == 'ENTERPRISE' ? (
<Row gutter={15}>
<Col span={12}>
<Form.Item label="法人"
name="legalPerson"
rules={[{required: true, message: '请输入法人'}]}
>
<Input placeholder="请输入法人"/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item<FormDataType>
label="成立时间"
name="establishDate"
rules={[{required: true, message: '请选择成立时间'}]}
>
<DatePicker placeholder="成立时间"
format={dateFormat}
locale={locale}
style={{width: '100%'}}
/>
</Form.Item>
</Col>
</Row>
) : <></>
}
<Row gutter={15}>
<Col span={12}>
<Form.Item label="联系地址"
name="contactAddress"
rules={[{required: true, message: '请输入联系地址'}]}
>
<Input placeholder="请输入联系地址"/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="联系电话"
name="contactPhone"
rules={[{required: true, message: '请输入联系电话'}]}
>
<Input placeholder="请输入联系电话"/>
</Form.Item>
</Col>
</Row>
<Form.Item wrapperCol={{span: 24}}>
<Flex align="center" justify="center" gap="large">
<Button type="primary"
htmlType="submit"
style={{backgroundColor: 'var(--color-primary)'}}>
</Button>
</Flex>
</Form.Item>
</Form>
<Spin tip="正在提交..." spinning={loading} fullscreen/>
{contextHolder}
</>
)
}