index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. import Authorization from '@/components/Authorization'
  2. import DatePicker from '@/components/DatePicker'
  3. import { contractReturnStore, tenderStore } from '@/store/mobx'
  4. import contractReturn from '@/store/mobx/contractReturn'
  5. import { iModalCommonProps } from '@/types/contract'
  6. import consts from '@/utils/consts'
  7. import { dayjsFormat, handleAutoCode } from '@/utils/util'
  8. import { Button, Form, Input, Modal, Select, Tree } from 'antd'
  9. import locale from 'antd/es/date-picker/locale/zh_CN'
  10. import dayjs from 'dayjs'
  11. import React, { ChangeEvent, useEffect, useState } from 'react'
  12. import { apiGetReturnWay } from '../Tabs/Receivable/api'
  13. import styles from './index.module.scss'
  14. const ContractModal: React.FC<iModalCommonProps> = ({ modalObj: { type, visible, confirmLoading }, onConfirm, onCancel, reload, row }) => {
  15. const { Option } = Select
  16. const [ form ] = Form.useForm()
  17. const [ options, setOptions ] = useState<string[]>([])
  18. const modalObj = {
  19. create: {
  20. title: '新建合同',
  21. cancelText: '取消',
  22. okText: '确认添加'
  23. },
  24. update: {
  25. title: '编辑合同',
  26. cancelText: '取消',
  27. okText: '确认'
  28. },
  29. close: {
  30. title: '关闭合同',
  31. cancelText: '取消',
  32. okText: '确认关闭'
  33. },
  34. del: {
  35. title: '删除合同',
  36. cancelText: '取消',
  37. okText: '确认删除'
  38. },
  39. unlock: {
  40. title: '解锁合同',
  41. cancelText: '取消',
  42. okText: '确认解锁'
  43. },
  44. return: {
  45. title: '添加回款',
  46. cancelText: '关闭',
  47. okText: '确认'
  48. }
  49. }
  50. useEffect(() => {
  51. if (visible) {
  52. form.setFieldsValue({ treeId: row.id, bidsectionId: row.bidsectionId })
  53. if (type === 'update') {
  54. const { content = '', name = '', price = '', partyA = '', partyB = '', partyASigner = '', partyBSigner = '', signerTime = '', remarks = '' } = contractReturnStore.contract
  55. form.setFieldsValue({ content, name, price, partyA, partyB, partyASigner, partyBSigner, signerTime: dayjs(signerTime), remarks })
  56. } else if (type === 'return') {
  57. apiGetReturnWay().then(({ code = -1, data = [] }) => {
  58. if (code === consts.RET_CODE.SUCCESS) {
  59. const options = data.map((item: string) => (
  60. <Option key={item} value={item}>
  61. {item}
  62. </Option>
  63. ))
  64. setOptions(options)
  65. }
  66. })
  67. form.setFieldsValue({ contractsId: contractReturnStore.contract.id })
  68. } else {
  69. form.setFieldsValue({ id: contractReturnStore.contract.id })
  70. }
  71. }
  72. }, [ visible ])
  73. const autoCode = async () => {
  74. const ruleArr = await handleAutoCode(tenderStore.tender.bidsectionId, 'contractReturnRule')
  75. form.setFieldsValue({ code: ruleArr.join('-') })
  76. }
  77. // 处理添加回款的金额不应该超出最大值
  78. const handleReturnPrice = (e: ChangeEvent<HTMLInputElement>) => {
  79. const maxPrice = parseFloat(contractReturnStore.contract.price) - parseFloat(contractReturnStore.contract.returned)
  80. console.log(maxPrice)
  81. if (parseFloat(e.target.value) > maxPrice) {
  82. form.setFieldsValue({ price: maxPrice })
  83. }
  84. }
  85. return (
  86. <Modal
  87. getContainer={false}
  88. visible={visible}
  89. title={modalObj[type]?.title}
  90. onCancel={onCancel}
  91. footer={
  92. <div className="pi-justify-end">
  93. {type === 'update' ? (
  94. <Authorization type="contract" auth="delete">
  95. <Button type="primary" key="delete" size="small" danger onClick={() => reload('del')}>
  96. 删除合同
  97. </Button>
  98. </Authorization>
  99. ) : null}
  100. <Button type="default" size="small" key="cancel" className="pi-btn-secondary" onClick={onCancel}>
  101. {modalObj[type]?.cancelText}
  102. </Button>
  103. <Button
  104. type="primary"
  105. size="small"
  106. key="ok"
  107. loading={confirmLoading}
  108. danger={type === 'del'}
  109. onClick={() => {
  110. form
  111. .validateFields()
  112. .then(values => {
  113. form.resetFields()
  114. if (type === 'update') {
  115. values.signerTime = dayjsFormat(values.signerTime, 'YYYY-MM-DD HH:mm:ss')
  116. }
  117. if (type === 'del') {
  118. delete values.warningText
  119. }
  120. if (type === 'return') {
  121. values.time = dayjsFormat(values.time, 'YYYY-MM-DD HH:mm:ss')
  122. }
  123. onConfirm(values, type)
  124. })
  125. .catch(info => {
  126. console.error('Validate Failed:', info)
  127. })
  128. }}>
  129. {modalObj[type]?.okText}
  130. </Button>
  131. </div>
  132. }>
  133. <Form form={form} layout="vertical" style={type === 'update' ? { maxHeight: '482px', overflowY: 'scroll', paddingRight: 5 } : { overflow: 'hidden' }}>
  134. <Form.Item name="bidsectionId" hidden>
  135. <Input />
  136. </Form.Item>
  137. {/* <Form.Item name="treeId" label="合同劳务" hidden>
  138. <Tree showLine={true} treeData={contractReturnStore.tree} />
  139. </Form.Item> */}
  140. <Form.Item name="treeId" label="合同劳务" hidden>
  141. <Input />
  142. </Form.Item>
  143. {type === 'create' ? (
  144. <>
  145. <Form.Item name="code" label="合同编号" rules={[ { required: true, message: '请输入合同编号' } ]} className={styles.contractFormItem}>
  146. <Input
  147. addonAfter={
  148. <span className="pi-pd-lr-11" onClick={() => autoCode()}>
  149. 自动编号
  150. </span>
  151. } />
  152. </Form.Item>
  153. <Form.Item name="name" label="合同名称" rules={[ { required: true, message: '请输入合同名称' } ]}>
  154. <Input placeholder="输入合同名称" />
  155. </Form.Item>
  156. {/* <Form.Item name="contractsType" label="合同类型" rules={[ { required: true, message: '请选择合同类型' } ]}>
  157. <Select showSearch>
  158. <Option value={1}>支出合同</Option>
  159. <Option value={2}>收入合同</Option>
  160. </Select>
  161. </Form.Item> */}
  162. <Form.Item name="price" label="合同金额" rules={[ { required: true, message: '请输入合同金额' } ]}>
  163. <Input type="number" placeholder="输入合同金额" addonAfter={<span>元</span>} />
  164. </Form.Item>
  165. </>
  166. ) : (
  167. ''
  168. )}
  169. {type === 'update' ? (
  170. <>
  171. <Form.Item name="content" label="项目内容" rules={[ { required: true, message: '请输入项目内容' } ]}>
  172. <Input />
  173. </Form.Item>
  174. <Form.Item name="name" label="合同名称" rules={[ { required: true, message: '请输入项目内容' } ]}>
  175. <Input />
  176. </Form.Item>
  177. <Form.Item name="price" label="合同金额" rules={[ { required: true, message: '请输入项目金额' } ]}>
  178. <Input />
  179. </Form.Item>
  180. <Form.Item name="partyA" label="甲方" rules={[ { required: true, message: '请输入甲方' } ]}>
  181. <Input />
  182. </Form.Item>
  183. <Form.Item name="partyASigner" label="甲方签约人" rules={[ { required: true, message: '请输入甲方签约人' } ]}>
  184. <Input />
  185. </Form.Item>
  186. <Form.Item name="partyB" label="乙方" rules={[ { required: true, message: '请输入乙方' } ]}>
  187. <Input />
  188. </Form.Item>
  189. <Form.Item name="partyBSigner" label="乙方签约人" rules={[ { required: true, message: '请输入乙方签约人' } ]}>
  190. <Input />
  191. </Form.Item>
  192. <Form.Item name="signerTime" label="合同签约日期" rules={[ { required: true, message: '请选择签约日期' } ]}>
  193. <DatePicker allowClear locale={locale} className="pi-width-100P" />
  194. </Form.Item>
  195. <Form.Item name="remarks" label="备注">
  196. <Input.TextArea maxLength={100} />
  197. </Form.Item>
  198. </>
  199. ) : (
  200. ''
  201. )}
  202. {type === 'close' ? (
  203. <>
  204. <Form.Item name="id" hidden>
  205. <Input />
  206. </Form.Item>
  207. <span>关闭后,合同将锁定,无法进行编辑、上传文件等操作。</span>
  208. </>
  209. ) : (
  210. ''
  211. )}
  212. {type === 'unlock' ? (
  213. <>
  214. <Form.Item name="id" hidden>
  215. <Input />
  216. </Form.Item>
  217. <span>解锁后,合同将锁定,无法进行编辑、上传文件等操作。</span>
  218. </>
  219. ) : (
  220. ''
  221. )}
  222. {type === 'del' ? (
  223. <>
  224. <Form.Item name="id" hidden>
  225. <Input />
  226. </Form.Item>
  227. <p className="mb-2">删除后,数据无法恢复,请谨慎操作。</p>
  228. <p className="mb-2">
  229. 请在下方文本框输入文本「<span className="pi-red">确认删除本合同</span>」,以此确认删除操作。
  230. </p>
  231. <Form.Item
  232. name="warningText"
  233. rules={[
  234. () => ({
  235. validator(rule, value) {
  236. if (!value || value !== '确认删除本合同') {
  237. return Promise.reject('请按照提示信息进行删除操作!')
  238. }
  239. return Promise.resolve()
  240. }
  241. })
  242. ]}>
  243. <Input placeholder="输入文本, 确认删除" />
  244. </Form.Item>
  245. </>
  246. ) : (
  247. ''
  248. )}
  249. {type === 'return' ? (
  250. <>
  251. <Form.Item name="contractsId" hidden>
  252. <Input />
  253. </Form.Item>
  254. <Form.Item name="time" label="回款日期" rules={[ { required: true, message: '请选择回款日期' } ]}>
  255. <DatePicker allowClear locale={locale} className="pi-width-100P" />
  256. </Form.Item>
  257. <Form.Item name="price" label="回款金额" rules={[ { required: true, message: '请选择回款金额' } ]}>
  258. <Input onChange={handleReturnPrice}/>
  259. </Form.Item>
  260. <Form.Item name="way" label="支付方式" rules={[ { required: true, message: '请选择回款方式' } ]}>
  261. <Select>{options}</Select>
  262. </Form.Item>
  263. <Form.Item name="remarks" label="备注">
  264. <Input.TextArea maxLength={100} />
  265. </Form.Item>
  266. </>
  267. ) : (
  268. ''
  269. )}
  270. </Form>
  271. </Modal>
  272. )
  273. }
  274. export default ContractModal