123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- import Authorization from '@/components/Authorization'
- import { ZhSubmitButton } from '@/components/Button'
- import OssUploadModal from '@/components/OssUpload'
- import { contractReturnStore, tenderStore } from '@/store/mobx'
- import { iIncomeTree, iShowTemplateState, iTemplateState } from '@/types/contract'
- import { iFile } from '@/types/file'
- import { apiSaveFileInfo } from '@/utils/common/api'
- import { contractConsts } from '@/utils/common/constStatus'
- import consts from '@/utils/consts'
- import { Button, Input, message, Radio, Table, Tabs } from 'antd'
- import Modal from 'antd/lib/modal/Modal'
- import { RadioChangeEvent } from 'antd/lib/radio'
- import { ColumnsType } from 'antd/lib/table'
- import { observer } from 'mobx-react'
- import React, { KeyboardEvent, useEffect, useRef, useState } from 'react'
- import { apiGetIncome, apiResfulContractTree, apiUpdateName, apiUpdateSerial } from '../../api'
- import { apiContractIncome, apiSetTemplate } from '../Modal/api'
- import Detail from '../Tabs/Detail'
- import File from '../Tabs/File'
- import Receivable from '../Tabs/Receivable'
- import styles from './index.module.scss'
- interface iTableContentPorps {
- changeModalType: (type: string) => void
- row: iIncomeTree
- setRow: (record: iIncomeTree) => void
- history: any
- }
- const GCsheet: React.FC<iTableContentPorps> = ({ changeModalType, row, setRow, history }) => {
- const [ sectionTemplate, setSectionTemplate ] = useState<iShowTemplateState>({
- isShow: false,
- template: '',
- loading: false
- })
- const [ tempalte, setTempalte ] = useState<{template1: iTemplateState, template2: iTemplateState}>({
- template1: {
- attribution: '',
- children: undefined,
- depth: 0,
- id: 0,
- isEnd: false,
- leaf: false,
- name: '',
- parentId: 0,
- serial: ''
- },
- template2: {
- attribution: '',
- children: undefined,
- depth: 0,
- id: 0,
- isEnd: false,
- leaf: false,
- name: '',
- parentId: 0,
- serial: ''
- }
- })
- // 阿里oss弹窗控制器
- const [ visible, setVisible ] = useState<boolean>(false)
- const { TabPane } = Tabs
- useEffect(() => {
- initData()
- }, [])
- const initData = async () => {
- const data = await apiContractIncome(tenderStore.bid)
- if (data.code === consts.RET_CODE.SUCCESS) {
- if (data.isTemplate && data.isTemplate === 1) {
- setSectionTemplate({
- ...sectionTemplate,
- isShow: true
- })
- setTempalte({
- ...tempalte,
- template1: data.sectionTemplate1,
- template2: data.sectionTemplate2
- })
- } else {
- contractReturnStore.updateTree(data.sectionTree.children)
- }
- }
- }
- interface HandleLabelProps {
- id: string
- bidsectionId: string
- name?: string
- }
- const handleNewLabel = async (type: string, payload: HandleLabelProps) => {
- let RET_CODE: number = -1
- if (type === 'create') {
- payload.name = inputEl.current?.state.value
- const { code = -1 } = await apiResfulContractTree('add', payload)
- RET_CODE = code
- }
- if (type === 'edit') {
- const name = inputEl.current?.state.value
- const { code = -1 } = await apiUpdateName(payload.id, payload.bidsectionId, name)
- RET_CODE = code
- }
- if (RET_CODE === consts.RET_CODE.SUCCESS) {
- contractReturnStore.resetTree(tenderStore.tender.bidsectionId)
- }
- }
- const codeChange = async (row: iIncomeTree, value: string) => {
- const { code = -1 } = await apiUpdateSerial(row.id, row.bidsectionId, value)
- if (code === consts.RET_CODE.SUCCESS) {
- initData()
- }
- }
- const inputEl = useRef<Input>(null)
- const modalColumns: ColumnsType<iTemplateState> = [
- {
- title: '项目节',
- dataIndex: 'serial',
- width: '30%',
- // eslint-disable-next-line react/display-name
- render: (text: string, row: iTemplateState) => {
- const { attribution = '', serial = '' } = row
- return <span>{`${attribution}${serial}`}</span>
- }
- },
- {
- title: '名称',
- dataIndex: 'name',
- width: '70%'
- }
- ]
- const TableColumns: ColumnsType<iIncomeTree> = [
- {
- title: '编号',
- dataIndex: 'code',
- width: '15%',
- // eslint-disable-next-line react/display-name
- render: (text: string, row: iIncomeTree) => {
- if (row.isEdit) {
- return (
- <Input
- defaultValue={row.serial}
- addonBefore={row.attribution}
- size="small"
- style={{ width: 80 }}
- onPressEnter={(e: KeyboardEvent<HTMLInputElement>) => codeChange(row, e.currentTarget.value)}
- />)
- } else {
- return <span>{row.code}</span>
- }
- // return <span>{row.code}</span>
- }
- },
- {
- title: '项目名称',
- dataIndex: 'name',
- render: (text:any, record: iIncomeTree) => {
- if (record.isEdit || record.isNew) {
- const type = record.isEdit ? 'edit' : 'create'
- return (
- <Input
- defaultValue={record.name}
- size="small"
- type="text"
- ref={inputEl}
- onPressEnter={() => handleNewLabel(type, { id: type === 'edit' ? record.id : record.parentId, bidsectionId: record.bidsectionId })}
- onBlur={() => handleNewLabel(type, { id: type === 'edit' ? record.id : record.parentId, bidsectionId: record.bidsectionId })}
- />)
- } else {
- return <span>{text}</span>
- }
- }
- },
- {
- title: '合同名称',
- dataIndex: 'contractName'
- },
- {
- title: '合同编号',
- dataIndex: 'contractCode'
- },
- {
- title: '合同金额',
- dataIndex: 'contractPrice',
- align: 'right',
- // eslint-disable-next-line react/display-name
- render: (text:any, record: iIncomeTree) => record.contractCode ? <span>{text}</span> : ''
- },
- {
- title: '回款金额',
- dataIndex: 'contractReturned',
- align: 'right',
- // eslint-disable-next-line react/display-name
- render: (text:any, record: iIncomeTree) => record.contractCode ? <span>{text}</span> : ''
- },
- {
- title: '状态',
- dataIndex: 'contractStatus',
- // eslint-disable-next-line react/display-name
- render: (_: any, record: iIncomeTree) => record.contractCode ? <span className={contractConsts[record.contractStatus].className}>{contractConsts[record.contractStatus].text}</span> : ''
- }
- ]
- // modal 确认 - 回调
- const handleModalConfirm = async () => {
- setSectionTemplate({
- ...sectionTemplate,
- loading: true
- })
- if (!sectionTemplate.template) {
- setSectionTemplate({
- ...sectionTemplate,
- loading: false
- })
- return message.error('请选择项目节模板!')
- }
- const { code = -1 } = await apiSetTemplate(sectionTemplate.template, tenderStore.tender.bidsectionId, 0)
- if (code === consts.RET_CODE.SUCCESS) {
- await initData()
- }
- setSectionTemplate({
- ...sectionTemplate,
- loading: false,
- isShow: false
- })
- }
- // modal 关闭 - 回调
- const handleModalCancel = () => {
- history.push('/console/contract/content/summary')
- }
- // 模板选择radio切换回调
- const handleRadioEvent = (e: RadioChangeEvent) => {
- if (e.target.checked) {
- setSectionTemplate({
- ...sectionTemplate,
- template: e.target.value
- })
- }
- }
- const onClickRow = (record: iIncomeTree) => {
- return {
- onClick() {
- rowClickHandler(record.id, record.bidsectionId, record.isEdit, record.isNew)
- },
- onDoubleClick() {
- contractReturnStore.rowChange(row.id)
- }
- }
- }
- // 行点击回调
- const rowClickHandler = async (id: string, bid: string, isEdit?: boolean, isNew?: boolean) => {
- if (!isEdit && !isNew) {
- const { code = -1, section = {}, contract: newContract = {} } = await apiGetIncome(id, bid)
- if (code === consts.RET_CODE.SUCCESS) {
- setRow(section)
- contractReturnStore.updateContract(newContract)
- }
- }
- }
- const handleRowClass = (record: iIncomeTree) => {
- return record.id === row.id ? 'ant-table-row-selected' : ''
- }
- const tabOnClick = (key: string) => {
- contractReturnStore.changeUpdate(key)
- }
- // 阿里oss上传弹窗
- const onShow = (show: boolean) => setVisible(show)
- const onCreate = async (fileList: iFile[]) => {
- const { code = -1 } = await apiSaveFileInfo(fileList, consts.DATA_TYPE.CONTRACT_RETURN, row.contractId)
- if (code === consts.RET_CODE.SUCCESS) {
- setVisible(false)
- contractReturnStore.changeUpdate('3')
- }
- }
- return sectionTemplate.isShow ?
- <Modal
- visible={sectionTemplate.isShow}
- maskClosable={false}
- title="选择合同项目节模板"
- okText="确定"
- confirmLoading={sectionTemplate.loading}
- cancelText="关闭"
- onCancel={handleModalCancel}
- closable={false}
- keyboard={false}
- onOk={() => handleModalConfirm()}
- width='70vw'
- >
- <div className={styles.modalWarnText}>默认项目节无法修改,可自行增加维护子节点</div>
- <div className={styles.modalTemplateContent}>
- <div className={styles.leftTemplate}>
- <div className="pi-pd-20">
- <Radio value="1" checked={sectionTemplate.template === '1'} onChange={(e: RadioChangeEvent) => handleRadioEvent(e)}><span className="pi-gray">项目节模板1</span></Radio>
- </div>
- <div className={styles.projectTable}>
- {
- tempalte.template1?.children && tempalte.template1?.children.length?
- <Table
- dataSource={tempalte.template1?.children}
- columns={modalColumns}
- pagination={false}
- bordered
- scroll={{ y: '300px' }}
- rowKey={record => record.id}
- defaultExpandAllRows={true}
- /> : ''
- }
- </div>
- </div>
- <div className={styles.rightTemplate}>
- <div className="pi-pd-20 pi-gray">
- <Radio value="2" checked={sectionTemplate.template === '2'} onChange={(e: RadioChangeEvent) => handleRadioEvent(e)}><span className="pi-gray">项目节模板2</span></Radio>
- </div>
- <div className={styles.projectTable}>
- {
- tempalte.template2?.children && tempalte.template2?.children.length?
- <Table
- dataSource={tempalte.template2?.children}
- columns={modalColumns}
- bordered
- pagination={false}
- scroll={{ y: '300px' }}
- rowKey={record => record.id}
- defaultExpandAllRows={true}
- />
- : ''
- }
- </div>
- </div>
- </div>
- </Modal>
- :
- <div className={styles.spreadContent}>
- <div className={styles.spreadSheets}>
- {
- contractReturnStore.showTable ?
- <Table<iIncomeTree>
- dataSource={contractReturnStore.tree}
- columns={TableColumns}
- bordered
- pagination={false}
- rowKey={record => record.id}
- defaultExpandAllRows={true}
- onRow={onClickRow}
- rowClassName={handleRowClass}
- style={{ height: '100%', overflowY: 'scroll' }}
- />
- : ''
- }
- </div>
- <div className={styles.extraControl}>
- <Tabs
- type="card"
- size="small"
- defaultActiveKey="1"
- onTabClick={(key: string) => tabOnClick(key)}
- tabBarExtraContent={{ right:
- <div className="pi-mg-right-5 pi-flex-row">
- {
- contractReturnStore.contract.id && contractReturnStore.contract.status === contractConsts.status.checking ?
- <>
- <Authorization type="contract" auth="add">
- <Button type="primary" size="small" onClick={() => changeModalType('update')} className="pi-mg-right-5">编辑合同</Button>
- </Authorization>
- <Button type="primary" size="small" onClick={() => changeModalType('return')} className="pi-mg-right-5">添加回款</Button>
- <Button type="primary" size="small" onClick={() => setVisible(true)}>上传文件</Button>
- </>
- : ''
- }
- {
- contractReturnStore.contract.id && contractReturnStore.contract.status === contractConsts.status.willClose ?
- <Button type="primary" size="small" danger className="pi-mg-right-3" onClick={() => changeModalType('close')}>关闭合同</Button>
- : ''
- }
- {
- contractReturnStore.contract.id && contractReturnStore.contract.status === contractConsts.status.closed ?
- <ZhSubmitButton type="primary" size="small" danger className="pi-mg-right-3" onClick={() => changeModalType('unlock')}>解锁合同</ZhSubmitButton>
- : ''
- }
- </div>
- }}>
- <TabPane key="1" tab="合同详情">
- <Detail {...contractReturnStore.contract} />
- </TabPane>
- <TabPane key="2" tab="合同回款">
- <Receivable />
- </TabPane>
- <TabPane key="3" tab="合同文件">
- <File />
- </TabPane>
- </Tabs>
- </div>
- <OssUploadModal
- visible={visible}
- onCancel={() => setVisible(false)}
- onCreate={onCreate}
- onShow={onShow}
- />
- </div>
- }
- export default observer(GCsheet)
|