123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- import Authorization from '@/components/Authorization'
- import DatePicker from '@/components/DatePicker'
- import MoneyInput from '@/components/MoneyInput'
- import { commonStore, contractStore, tenderStore } from '@/store/mobx'
- import { ContractType } from '@/store/mobx/contract'
- import { iModalCommonProps } from '@/types/contract'
- import { apiContractSection } from '@/utils/common/api'
- import { contractTreeBaseId } from '@/utils/common/constStatus'
- import consts from '@/utils/consts'
- import { dayjsFormat, handleAutoCode } from '@/utils/util'
- import { Button, Form, Input, Modal, Select, TreeSelect } from 'antd'
- import locale from 'antd/es/date-picker/locale/zh_CN'
- import dayjs from 'dayjs'
- import React, { useEffect, useState } from 'react'
- import styles from './index.module.scss'
- import { BigNumber } from "bignumber.js"
- import { observer } from 'mobx-react'
- interface ContractSection {
- id: string;
- treeType: number;
- parentId: string;
- name: string;
- depth: number;
- serial: number;
- attribution: string;
- code: string;
- projectId: string;
- bidsectionId: string;
- contractId: string;
- contractName: string;
- contractCode: string;
- contractPrice: string;
- contractReturned: string;
- contractsPaid: string;
- contractStatus: number;
- contractLocking: number;
- createTime: string;
- children?: any;
- templateNumber: number;
- operation: string;
- elderBrother: boolean;
- isEnd: boolean;
- key: string;
- title: string;
- }
- const ContractModal: React.FC<iModalCommonProps> = ({ modalObj: { type, visible, confirmLoading, contractType }, onConfirm, onCancel, reload, row }) => {
- const { Option } = Select
- const [ contractSection, setContractSection ] = useState<ContractSection[]>([])
- const [ form ] = Form.useForm()
- const modalObj = {
- create: {
- title: '新建合同',
- cancelText: '取消',
- okText: '确认添加'
- },
- update: {
- title: '编辑合同',
- cancelText: '取消',
- okText: '确认'
- },
- close: {
- title: '关闭合同',
- cancelText: '取消',
- okText: '确认关闭'
- },
- del: {
- title: '删除合同',
- cancelText: '取消',
- okText: '确认删除'
- },
- unlock: {
- title: '解锁合同',
- cancelText: '取消',
- okText: '确认解锁'
- },
- add: {
- title: contractType === ContractType.INCOME ? '添加回款' : '添加支付',
- cancelText: '关闭',
- okText: '确认'
- }
- }
- const initTreeSection = async () => {
- const { code = -1, sectionTree: data = {} } = await apiContractSection(tenderStore.bid, contractType === ContractType.INCOME ? consts.CONTRACT_TREE.RETURN : consts.CONTRACT_TREE.PAID)
- if (code === consts.RET_CODE.SUCCESS) {
- setContractSection(data.children)
- }
- }
- useEffect(() => {
- if (visible) {
- form.setFieldsValue({ treeId: row.id, bidsectionId: tenderStore.bid })
- if (type === 'create') {
- initTreeSection()
- form.setFieldsValue({ treeId: row.contractId === contractTreeBaseId ? row.id : row.parentId })
- }
- if (type === 'update') {
- const { content = '', name = '', price = 0, partyA = '', partyB = '', partyASigner = '', partyBSigner = '', signerTime = '', remarks = '' } = contractStore.contract
- form.setFieldsValue({ content, name, price, partyA, partyB, partyASigner, partyBSigner, signerTime: signerTime ? dayjs(signerTime) : '', remarks })
- } else if (type === 'add') {
- commonStore.returnWayOptions && commonStore.queryWayOptions()
- form.setFieldsValue({ contractsId: contractStore.contract.id })
- } else {
- form.setFieldsValue({ id: contractStore.contract.id })
- }
- }
- }, [ visible ])
- const autoCode = async () => {
- const ruleArr = await handleAutoCode(tenderStore.tender.bidsectionId, contractType === ContractType.INCOME ? 'contractReturnRule' : 'contractPaidRule')
- form.setFieldsValue({ code: ruleArr.join('-') })
- }
- // 处理添加回款的金额不应该超出最大值
- const maxPrice = new BigNumber(contractStore.contract.price).minus(contractType === ContractType.INCOME ? contractStore.contract.returned : contractStore.contract.paid)
- const minPrice = new BigNumber(contractType === ContractType.INCOME ? row.contractReturned : row.contractsPaid)
- return (
- <Modal
- getContainer={false}
- visible={visible}
- title={modalObj[type]?.title}
- onCancel={() => {
- form.resetFields()
- onCancel()
- }}
- footer={
- <div className="pi-justify-end">
- {type === 'update' ? (
- <Authorization type="contract" auth="delete">
- <Button type="primary" key="delete" size="small" danger onClick={() => reload('del')}>
- 删除合同
- </Button>
- </Authorization>
- ) : null}
- <Button type="default" size="small" key="cancel" className="pi-btn-secondary" onClick={() => {
- form.resetFields()
- onCancel()
- }}>
- {modalObj[type]?.cancelText}
- </Button>
- <Button
- type="primary"
- size="small"
- key="ok"
- loading={confirmLoading}
- danger={type === 'del'}
- onClick={() => {
- form
- .validateFields()
- .then(values => {
- form.resetFields()
- if (type === 'update') {
- values.signerTime = dayjsFormat(values.signerTime, 'YYYY-MM-DD HH:mm:ss')
- values.price = parseFloat(values.price)
- }
- if (type === 'del') {
- delete values.warningText
- }
- if (type === 'add') {
- values.time = dayjsFormat(values.time, 'YYYY-MM-DD HH:mm:ss')
- values.price = parseFloat(values.price)
- }
- onConfirm(values, type)
- })
- .catch(info => {
- console.error('Validate Failed:', info)
- })
- }}>
- {modalObj[type]?.okText}
- </Button>
- </div>
- }>
- <Form form={form} layout="vertical" style={type === 'update' ? { maxHeight: '482px', overflowY: 'scroll', paddingRight: 5 } : { overflow: 'hidden' }}>
- <Form.Item name="bidsectionId" hidden>
- <Input />
- </Form.Item>
- <Form.Item name="treeId" label="合同劳务" hidden={type === 'create' ? false : true} rules={[ { required: true, message: '请选择项目节' } ]}>
- <TreeSelect treeData={contractSection} />
- </Form.Item>
- {/* <Form.Item name="treeId" label="合同劳务" hidden>
- <Input />
- </Form.Item> */}
- {type === 'create' ? (
- <>
- <Form.Item name="code" label="合同编号" rules={[ { required: true, message: '请输入合同编号' } ]} className={styles.contractFormItem}>
- <Input
- autoComplete='off'
- addonAfter={
- <span className="pi-pd-lr-11" onClick={() => autoCode()}>
- 自动编号
- </span>
- } />
- </Form.Item>
- <Form.Item name="name" label="合同名称" rules={[ { required: true, message: '请输入合同名称' } ]}>
- <Input placeholder="输入合同名称" autoComplete='off'/>
- </Form.Item>
- {/* <Form.Item name="contractsType" label="合同类型" rules={[ { required: true, message: '请选择合同类型' } ]}>
- <Select showSearch>
- <Option value={1}>支出合同</Option>
- <Option value={2}>收入合同</Option>
- </Select>
- </Form.Item> */}
- <Form.Item label="合同金额" name="price" rules={[ { required: true, message: '请输入合同金额' } ]} className={styles.MoneyFormItem}>
- {/* <Input type="number" placeholder="输入合同金额" addonAfter={<span>元</span>} /> */}
- <MoneyInput />
- </Form.Item>
- </>
- ) : (
- ''
- )}
- {type === 'update' ? (
- <>
- <Form.Item name="content" label="项目内容" rules={[ { required: true, message: '请输入项目内容' } ]}>
- <Input />
- </Form.Item>
- <Form.Item name="name" label="合同名称" rules={[ { required: true, message: '请输入项目内容' } ]}>
- <Input />
- </Form.Item>
- <Form.Item label="合同金额" name="price" rules={[ { required: true, message: '请输入合同金额' }, () => ({
- validator(_, value) {
- if (value && (new BigNumber(value).lt(minPrice))) {
- return Promise.reject(`当前金额不能低于${minPrice}`)
- }
- return Promise.resolve()
- }
- }) ]}>
- <MoneyInput />
- </Form.Item>
- <Form.Item name="partyA" label="甲方" rules={[ { required: true, message: '请输入甲方' } ]}>
- <Input />
- </Form.Item>
- <Form.Item name="partyASigner" label="甲方签约人" rules={[ { required: true, message: '请输入甲方签约人' } ]}>
- <Input />
- </Form.Item>
- <Form.Item name="partyB" label="乙方" rules={[ { required: true, message: '请输入乙方' } ]}>
- <Input />
- </Form.Item>
- <Form.Item name="partyBSigner" label="乙方签约人" rules={[ { required: true, message: '请输入乙方签约人' } ]}>
- <Input />
- </Form.Item>
- <Form.Item name="signerTime" label="合同签约日期" rules={[ { required: true, message: '请选择签约日期' } ]}>
- <DatePicker allowClear locale={locale} className="pi-width-100P" />
- </Form.Item>
- <Form.Item name="remarks" label="备注">
- <Input.TextArea maxLength={100} />
- </Form.Item>
- </>
- ) : null
- }
- {type === 'close' ? (
- <>
- <Form.Item name="id" hidden>
- <Input />
- </Form.Item>
- <span>关闭后,合同将锁定,无法进行编辑、上传文件等操作。</span>
- </>
- ) : (
- ''
- )}
- {type === 'unlock' ? (
- <>
- <Form.Item name="id" hidden>
- <Input />
- </Form.Item>
- <span>解锁后,合同可进行编辑、上传文件等操作。</span>
- </>
- ) : (
- ''
- )}
- {type === 'del' ? (
- <>
- <Form.Item name="id" hidden>
- <Input />
- </Form.Item>
- <p className="mb-2">删除后,数据无法恢复,请谨慎操作。</p>
- <p className="mb-2">
- 请在下方文本框输入文本「<span className="pi-red">确认删除本合同</span>」,以此确认删除操作。
- </p>
- <Form.Item
- name="warningText"
- rules={[
- () => ({
- validator(rule, value) {
- if (!value || value !== '确认删除本合同') {
- return Promise.reject('请按照提示信息进行删除操作!')
- }
- return Promise.resolve()
- }
- })
- ]}>
- <Input placeholder="输入文本, 确认删除" />
- </Form.Item>
- </>
- ) : (
- ''
- )}
- {type === 'add' ? (
- <>
- <Form.Item name="contractsId" hidden>
- <Input />
- </Form.Item>
- <Form.Item name="time" label={`${contractType === ContractType.INCOME ? '回款' : '支付'}日期`} rules={[ { required: true, message: `请选择${contractType === ContractType.INCOME ? '回款' : '支付'}日期` } ]}>
- <DatePicker allowClear locale={locale} className="pi-width-100P" />
- </Form.Item>
- <Form.Item name="price" label={`${contractType === ContractType.INCOME ? '回款' : '支付'}金额`} rules={[ { required: true, message: `请输入${contractType === ContractType.INCOME ? '回款' : '支付'}金额` }, () => ({
- validator(_, value) {
- if (value && (new BigNumber(value).gt(maxPrice))) {
- return Promise.reject(`当前金额不能大于${maxPrice}`)
- }
- return Promise.resolve()
- }
- }) ]}>
- {/* <Input onChange={handleReturnPrice}/> */}
- <MoneyInput />
- </Form.Item>
- <Form.Item name="way" label={`${contractType === ContractType.INCOME ? '回款' : '支付'}方式`} rules={[ { required: true, message: `请选择${contractType === ContractType.INCOME ? '回款' : '支付'}方式` } ]}>
- <Select>
- {
- commonStore.returnWayOptions.map(item => (
- <Option key={item} value={item}>
- {item}
- </Option>))
- }
- </Select>
- </Form.Item>
- <Form.Item name="remarks" label="备注">
- <Input.TextArea maxLength={100} />
- </Form.Item>
- </>
- ) : (
- ''
- )}
- </Form>
- </Modal>
- )
- }
- export default observer(ContractModal)
|