system-copyright-react/src/route/proj/ProjNew.tsx
2025-02-26 16:57:47 +08:00

622 lines
29 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import './proj-new.css';
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import { Button, Flex, Form, Input, message, Modal, Spin, Checkbox, DatePicker, Select } from "antd";
import { useContext, useEffect, useState } from "react";
import { get, post } from "../../util/AjaxUtils.ts";
// import {GlobalContext} from "../../context/GlobalContext.ts";
import {
// IProjCharge,
ProjAdditionalType, ProjChargeType
} from "../../interfaces/proj/IProj.ts";
import locale from 'antd/es/date-picker/locale/zh_CN';
import { GlobalDispatchContext, reloadUser } from "../../context/GlobalContext.ts";
import BelongPeople from '../../components/BelongPeople/BelongPeople.tsx'
import ContactPeople from '../../components/ContactPeople/ContactPeople.tsx'
import dayjs from 'dayjs';
import SelectCouponModal from '../../components/CouponModal/SelectCouponModal.tsx'
// const { TextArea } = Input;
type ProjInfo = {
projName: string;
projIntroduction: string;
belongPeople: string;
contacts: string;
projDevCompleteDate: string;
coupon?: string;
projVersion: string;
backendCodeLang: string;
};
export default function ProjNew() {
// 是否显示优惠券
const [couponShow, setcouponShow] = useState(true)
// const globalContext = useContext(GlobalContext);
const dateFormat = 'YYYY年MM月DD日';
const globalDispatchContext = useContext(GlobalDispatchContext);
const nav = useNavigate();
const pathParams = useParams();
const [queryParams] = useSearchParams();
const [messageApi, contextHolder] = message.useMessage();
const [loading, setLoading] = useState<boolean>(false);
const height = window.innerHeight - 180;
// 提示结尾是否带关键字弹窗
// const [hasKeywords, setHasKeywords] = useState<boolean>(false);
// 创建项目弹窗
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [chargePrice, setChargePrice] = useState(0);
const [projInfo, setProjInfo] = useState<ProjInfo>({
projName: '',
projIntroduction: '',
belongPeople: '',
contacts: '',
projDevCompleteDate: '',
projVersion: '',
backendCodeLang: '',
});
const [form] = Form.useForm<ProjInfo>();
// 所属者弹窗
const [belongModal, setBelongModal] = useState(false)
// 联系人弹窗
const [concatModal, setConcatModal] = useState(false)
// const [belongPeopleName ,setBelongPeopleName] = useState('')
const [belongPeopleInfo, setBelongPeopleInfo] = useState({
authorName: '',
authorType: '',
authorIdCardType: '',
authorIdCard: '',
authorCrcAccount: '',
authorId: '',
authorProvinceCity: ''
})
const [concatPeopleInfo, setConcatPeopleInfo] = useState({
applyConcatId: '',
applyContactCsaNo: '',
applyContactEmail: '',
applyContactName: '',
applyContactPhone: '',
applyContactCompany: ''
})
// 优惠券弹窗
const [couponModal, setCouponModal] = useState(false)
const setValue = (value: string) => {
form.setFieldsValue({
belongPeople: value
})
}
const setConcatValue = (value: string) => {
form.setFieldsValue({
contacts: value
})
}
const [createProjId, setCreateProjId] = useState('');
const oldlistProjChargeAdditional: string[] = [];
const [listProjChargeAdditional, setlistProjChargeAdditional] = useState<string[]>([])
// 是否可用优惠券
const [hasCoupon, setHasCoupon] = useState(false)
// 给优惠券栏赋值
const setCouponTitle = (value: string) => {
form.setFieldsValue({
coupon: value
});
}
// 优惠券id
const [couponId, setCouponId] = useState('')
// 优惠券减的钱数
const [couponNum, setCouponNum] = useState(0)
// 查看是否有可用获取优惠券信息
const getCouponData = () => {
get({
messageApi,
url: `/api/coupon/user/listpage/self`,
// url: `/api/proj/refund/apply/listpage?applyStatus=${state.type}`,
config: {
params: {
page: 1,
rows: 10,
isEffective: 1,
isUsed: 0,
}
},
onBefore() {
},
onSuccess(data: any) {
if (data.data.rows.length > 0) {
setHasCoupon(true)
}
},
onFinally() {
},
})
}
//判断是否以“软件”、“系统”、“平台”或“APP”结尾
function isEndsWithKeywords(str: string) {
const keywords = ["软件", "系统", "平台", "APP"];
return keywords.some(keyword => str.endsWith(keyword));
}
// 提示信息是否显示
const [showTip, setShowTip] = useState(false)
useEffect(() => {
get({
messageApi: messageApi,
url: '/api/proj/charge/get',
onSuccess({ data }) {
// console.log(data);
const charge = data as any;
// console.log('创建页price',charge.proj.materialAgent);
let price = 0;
switch (pathParams.projChargeType) {
case ProjChargeType.ALL:
// price = charge.proj.all;
price = charge.projTypes[0].price;
break;
// case ProjChargeType.MATERIAL_AGENT:
// price = charge.proj.materialAgent;
// break;
// case ProjChargeType.MATERIAL_AGENT_URGENT:
// price = charge.proj.materialAgentUrgent;
// break;
case ProjChargeType.MATERIAL:
price = charge.projTypes[1].price;
break;
case ProjChargeType.FREE:
price = charge.projTypes[2].price;
break;
default:
messageApi.error({
type: 'error',
content: '价格类型错误',
})
}
const pkg = queryParams.get('pkg') == 'true' ? true : false
const videoDemo = queryParams.get('videoDemo') == 'true' ? true : false
const urgent = queryParams.get('urgent') == 'true' ? true : false
if (pkg) {
price += charge.additional.pkg;
oldlistProjChargeAdditional.push(ProjAdditionalType.PKG);
// console.log(listProjChargeAdditional);
}
if (videoDemo) {
price += charge.additional.videoDemo;
oldlistProjChargeAdditional.push(ProjAdditionalType.VIDEO_DEMO);
// console.log(listProjChargeAdditional);
}
if (urgent) {
price += charge.additional.urgent;
oldlistProjChargeAdditional.push(ProjAdditionalType.URGENT);
// console.log(listProjChargeAdditional);
}
setChargePrice(price);
setlistProjChargeAdditional(oldlistProjChargeAdditional)
// console.log('传递信息pkg:',pkg,'videoDemo:',videoDemo);
}
})
// console.log('类型', pathParams.projChargeType);
if (pathParams.projChargeType == 'FREE') {
setcouponShow(false)
}
getCouponData()
}, []);
return (
<>
{contextHolder}
{/* <Breadcrumb
items={[
{title: <Link to={'/'}>首页</Link>},
{title: <Link to={'/proj-create'}>创建项目</Link>},
{title: '新建项目'},
]}
/> */}
<div className='projNew' style={{ height: `${height}px`, overflow: 'auto' }}>
<div className="proj-new">
{/* <div className="proj-title">请完善项目的基本信息</div> */}
<div className="proj-form">
<Form
name="basic"
form={form}
initialValues={{
projVersion: 'V1.0',
backendCodeLang: 'JAVA'
}} // 添加 initialValues 属性
layout={'vertical'}
labelCol={{ span: 24 }}
wrapperCol={{ span: 24 }}
style={{ width: '100%' }}
onFinish={(formData) => {
setIsCreateModalOpen(true);
setProjInfo({
projName: formData.projName,
projIntroduction: formData.projIntroduction,
belongPeople: formData.belongPeople,
contacts: formData.contacts,
projDevCompleteDate: formData.projDevCompleteDate,
projVersion: formData.projVersion ? formData.projVersion : 'V1.0',
backendCodeLang: formData.backendCodeLang,
})
}}
autoComplete="off"
>
<div style={{ position: 'relative' }}>
<div className='formItemOne'>
<div className='formItem-title oneTitle'>*</div>
<Form.Item<ProjInfo>
name="projName"
rules={[
{ required: true, message: '请输入系统全称' },
]}
>
<Input onChange={(e) => {
// 打印值
// console.log(e.target.value);
if (e.target.value) {
if (isEndsWithKeywords(e.target.value)) {
setShowTip(false)
} else {
setShowTip(true)
}
} else {
setShowTip(false)
}
}} style={{ background: '#eeeeee', width: '800px', height: '50px', fontSize: '16px' }} placeholder="请输入系统全称 (注系统全称建议以“软件”、“系统”、“平台”或“APP”结尾)" />
</Form.Item>
</div>
<div style={{
position: 'absolute', left: 185,
display: showTip ? 'unset' : 'none',
color: 'green',
}}>APP</div>
</div>
<div className='formItemOne' style={{ marginTop: 20 }}>
<div className='formItem-title oneTitle'>*</div>
<Form.Item<ProjInfo>
name="projVersion"
>
<Input
style={{ background: '#eeeeee', width: '800px', height: '50px', fontSize: '16px' }} placeholder="请输入系统版本 (注默认版本为v1.0)" />
</Form.Item>
</div>
<div className='formItemOne' style={{ marginTop: 20 }}>
<div className='formItem-title oneTitle'>*</div>
<Form.Item<ProjInfo>
name="backendCodeLang"
rules={[
{ required: true, message: '请选择系统语言' },
]}
>
<Select
style={{ width: '800px', height: '50px', fontSize: '16px' }}
placeholder="请选择系统语言"
className='langselect'
// defaultValue="JAVA"
options={[
{ value: 'JAVA', label: 'JAVA' },
{ value: 'NODE', label: 'NODE(JAVASCRIPT)' },
{ value: 'PYTHON', label: 'PYTHON' },
{ value: 'GO', label: 'GO' },
]}
>
</Select>
</Form.Item>
</div>
<div className='formItemOne' style={{ marginTop: 20, position: 'relative' }}>
<div className='formItem-title '>
*
</div>
<Form.Item<ProjInfo>
name="belongPeople"
rules={[{ required: true, message: '请选择/创建知识产权所属者' }]}
>
<Input style={{ background: '#eeeeee', width: '800px', height: '50px', fontSize: '16px', color: '#3B3B3B' }} placeholder="请选择/创建知识产权所属者" disabled />
</Form.Item>
<div style={{
position: 'absolute', right: 20, fontSize: 16, color: " #1F79FF", cursor: 'pointer',
// background:'pink',
width: 780,
textAlign: 'right',
}} onClick={() => {
setBelongModal(true)
}}></div>
</div>
<div className='formItemOne' style={{ marginTop: 20, position: 'relative' }}>
<div className='formItem-title '>
*
</div>
<Form.Item<ProjInfo>
name="contacts"
rules={[{ required: true, message: '请选择/创建知识产权联系人' }]}
>
<Input style={{ background: '#eeeeee', width: '800px', height: '50px', fontSize: '16px', color: '#3B3B3B' }} placeholder="请选择/创建知识产权联系人" disabled />
</Form.Item>
<div style={{
position: 'absolute', right: 20, fontSize: 16, color: " #1F79FF", cursor: 'pointer',
width: 780,
textAlign: 'right',
}} onClick={() => {
setConcatModal(true)
}}></div>
</div>
<div className='formItemOne' style={{ marginTop: 20 }}>
<div className='formItem-title '>
</div>
<Form.Item<ProjInfo>
// label="开发完成时间"
name="projDevCompleteDate"
// rules={[{ required: true, message: '请输入开发完成时间' }]}
>
<DatePicker placeholder="请选择开发完成日期"
format={dateFormat}
locale={locale}
// style={{ width: '100%' }}
style={{ height: '50px', width: '800px', fontSize: 16, background: '#eeeeee', }}
disabledDate={(current) => current && current > dayjs().endOf('day')}
/>
</Form.Item>
</div>
<div style={{ display: couponShow ? 'unset' : 'none' }}>
<div className='formItemOne' style={{ marginTop: 20, position: 'relative' }}>
<div className='formItem-title '>
</div>
<Form.Item<ProjInfo>
name="coupon"
// rules={[{ required: true, message: '请选择优惠券' }]}
>
<Input style={{ background: '#eeeeee', fontSize: 16, width: '800px', height: '50px', color: '#3B3B3B' }} placeholder={hasCoupon ? '请选择优惠券' : '暂无可用优惠券'} disabled />
</Form.Item>
<div style={{ position: 'absolute', right: 23, fontSize: 16, color: hasCoupon ? '#1F79FF' : '#676767', cursor: 'pointer' }} onClick={() => {
if (hasCoupon) {
setCouponModal(true)
// #1F79FF
} else {
messageApi.error('无可用优惠券')
}
}}></div>
</div>
</div>
<div className='software-protocol'>
<Form.Item
name="agreement"
valuePropName="checked"
rules={[
{
validator: (_, value) =>
value ? Promise.resolve() : Promise.reject(new Error('请阅读并勾选《软件委托开发协议》')),
},
]}
>
<Checkbox>
<a onClick={() => {
window.open('https://www.aimzhu.com/Seda.html')
}}></a>
</Checkbox>
</Form.Item>
</div>
{/* <div className='formItemTwo'>
<div className='formItem-title '>简单描述</div>
<Form.Item<ProjInfo>
name="projIntroduction"
>
<TextArea rows={10} style={{ background: '#eeeeee', resize: 'none',width:"328px",height:'220px',fontSize:'16px' }} placeholder="请对系统作出简单的描述,以使可准确生成资料..." />
</Form.Item>
</div> */}
<div style={{ marginTop: '' }}>
<Form.Item>
<Flex align="center" justify="center" gap="large">
<Button
// style={{
// backgroundColor: '#F5F5F5', width: '216px',
// height: '50px', color: '#AFAFAF', fontSize: '16px'
// }}
size='large'
type="default" htmlType="button" onClick={() => {
nav(-1);
}}
>
</Button>
<Button type="primary" htmlType="submit"
size='large'
// style={{
// backgroundColor: 'var(--color-primary)', width: '216px',
// height: '50px', fontSize: '16px', marginLeft: '53px'
// }}
// onClick={()=>{
// alert(belongPeopleInfo.authorProvinceCity)
// }}
>
</Button>
</Flex>
</Form.Item>
</div>
</Form>
</div>
</div>
</div>
<Modal title="提示"
centered
okText="确定"
cancelText="取消"
open={isCreateModalOpen}
onOk={() => {
// console.log('最终',listProjChargeAdditional);
// console.log(belongPeopleInfo.authorId);
post<any>({
messageApi,
url: '/api/proj/create',
body: {
projName: projInfo.projName,
projVersion: projInfo.projVersion,
backendCodeLang: projInfo.backendCodeLang,
projChargeType: pathParams.projChargeType,
listProjChargeAdditional: listProjChargeAdditional,
// dayjs(formInfo.getFieldValue('projDevCompleteDate')).format(dateFormat),
projDevCompleteDate: projInfo.projDevCompleteDate ? dayjs(projInfo.projDevCompleteDate).format(dateFormat) : '',
authorCrcAccount: belongPeopleInfo.authorCrcAccount,
authorId: belongPeopleInfo.authorId,
authorIdCard: belongPeopleInfo.authorIdCard,
authorIdCardType: belongPeopleInfo.authorIdCardType,
authorName: belongPeopleInfo.authorName,
authorProvinceCity: belongPeopleInfo.authorProvinceCity,
authorType: belongPeopleInfo.authorType,
applyContactCompany: concatPeopleInfo.applyContactCompany,
applyContactCsaNo: concatPeopleInfo.applyContactCsaNo,
applyContactEmail: concatPeopleInfo.applyContactEmail,
applyContactId: concatPeopleInfo.applyConcatId,
applyContactName: concatPeopleInfo.applyContactName,
applyContactPhone: concatPeopleInfo.applyContactPhone,
couponId: couponId ? couponId : '',
},
onBefore() {
setLoading(true);
},
onSuccess({ data }) {
setIsEditModalOpen(true);
setCreateProjId(data.data);
reloadUser(messageApi, globalDispatchContext).then(() => {
messageApi.success('扣款成功');
});
},
onFinally() {
setLoading(false);
}
})
setIsCreateModalOpen(false);
}}
onCancel={() => {
setIsCreateModalOpen(false);
}}>
<div> {(chargePrice / 100 - couponNum) < 0 ? 0 : chargePrice / 100 - couponNum} </div>
</Modal>
<Modal title="提示"
okText="确定"
cancelText="取消"
open={isEditModalOpen}
onOk={() => {
sessionStorage.setItem('projName', projInfo.projName);
if (pathParams.projChargeType == ProjChargeType.ALL) {
nav(`/proj-eall/${createProjId}`);
} else if (pathParams.projChargeType == ProjChargeType.FREE) {
nav(`/proj-efree/${createProjId}`);
} else {
nav(`/proj-edit/${createProjId}`);
}
}}
onCancel={() => {
setIsEditModalOpen(false);
}}>
<div></div>
</Modal>
{/* <Modal title="提示"
okText="更改"
cancelText="继续"
open={hasKeywords}
onOk={() => {
//Form表单的projName变为空
form.resetFields(['projName']);
setHasKeywords(false);
}}
centered
onCancel={() => {
setHasKeywords(false);
setIsCreateModalOpen(true);
}}>
<div>系统全称建议以“软件”、“系统”、“平台”或“APP”结尾是否更改</div>
</Modal> */}
<Modal title="选择联系人"
destroyOnClose
open={concatModal}
width={1200}
footer={null}
onCancel={() => {
setConcatModal(false)
}}>
<ContactPeople isShow={true} closeModal={() => { setConcatModal(false) }} setConcatPeopleInfo={setConcatPeopleInfo} concatPeopleInfo={concatPeopleInfo} setConcatValue={setConcatValue}></ContactPeople>
</Modal>
<Modal title="选择所属者"
destroyOnClose
open={belongModal}
width={1200}
footer={null}
onCancel={() => {
setBelongModal(false)
}}>
<BelongPeople closeModal={() => { setBelongModal(false) }} setBelongPeopleInfo={setBelongPeopleInfo} belongPeopleInfo={belongPeopleInfo} setValue={setValue} isShow={true}></BelongPeople>
</Modal>
<Modal title="选择优惠券"
destroyOnClose
open={couponModal}
width={809}
footer={null}
onCancel={() => {
setCouponModal(false)
}}>
<SelectCouponModal
couponId={couponId}
setCouponId={(value: string) => {
setCouponId(value)
}}
couponNum={couponNum}
setCouponNum={(value: number) => {
setCouponNum(value)
}}
setCouponTitle={(value: string) => {
setCouponTitle(value)
}}
closeModal={() => {
setCouponModal(false)
}}
></SelectCouponModal>
</Modal>
<Spin tip="正在提交..." spinning={loading} fullscreen />
</>
)
}