index.tsx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
  2. import styles from './index.module.scss'
  3. import { pageTitTxtObj } from '@/pages/D_storeManage/D4impStor/D4edit'
  4. import { useParams } from 'react-router-dom'
  5. import { Button, DatePicker, Input, Select } from 'antd'
  6. import { statusObj } from '@/utils/tableData'
  7. import { FourTableType } from '@/pages/B_enterTibet/B1collect/type'
  8. import dayjs from 'dayjs'
  9. import { selectObj } from '@/utils/select'
  10. import Z3upFiles from '@/components/Z3upFiles'
  11. import ZRichTexts from '@/components/ZRichTexts'
  12. import MyPopconfirm from '@/components/MyPopconfirm'
  13. import history, { btnFlagFu2 } from '@/utils/history'
  14. import { MessageFu } from '@/utils/message'
  15. import X3auditInfo from '@/pages/X_stock/X3auditInfo'
  16. import {
  17. E1_APIcreate,
  18. E1_APIdel,
  19. E1_APIgetGoodsList,
  20. E1_APIgetInfo,
  21. E1_APIrevocation,
  22. E1_APIsaveApply,
  23. E1_APIsaveAudit,
  24. E1_APIsaveCreate,
  25. E1_APIsaveDraft
  26. } from '@/store/action/E1accident'
  27. import { EXbtnFu } from '@/utils/EXBtn'
  28. import ZflowTable from '@/components/ZflowTable'
  29. import ZupFileTable from '@/components/ZupFileTable'
  30. import { API_goodsInfo } from '@/store/action/C1ledger'
  31. function E1edit() {
  32. const { key, id } = useParams<any>()
  33. // key:1 新增 2编辑 3审批 4查看
  34. // 事故藏品选择编号类型
  35. const [goodsArr, setGoodsArr] = useState<{ value: string; label: string; num: string }[]>([])
  36. const numNameChangeFu = useCallback(async (val: string) => {
  37. const res = await E1_APIgetGoodsList(val)
  38. if (res.code === 0) {
  39. const arr = res.data || []
  40. setGoodsArr(
  41. arr.map((v: any) => ({
  42. num: v.num,
  43. label: v.name,
  44. value: v.id + ''
  45. }))
  46. )
  47. }
  48. }, [])
  49. // 滚到顶部
  50. const sollrDom = useRef<HTMLDivElement>(null)
  51. // 顶部数据
  52. const [topInfo, setTopInfo] = useState({} as FourTableType)
  53. // 创建订单
  54. const creatFu = useCallback(async () => {
  55. const res = await E1_APIcreate()
  56. if (res.code === 0) {
  57. const obj = res.data
  58. // 从藏品详情点击按钮进来
  59. const urlAll = window.location.href
  60. if (urlAll.includes('?id=')) {
  61. const urlId = urlAll.split('?id=')[1]
  62. const res2 = await API_goodsInfo(Number(urlId))
  63. if (res2.code === 0) {
  64. obj.numName = res2.data.numName
  65. numNameChangeFu(res2.data.numName)
  66. obj.goodsIds = urlId
  67. setTopInfo(obj)
  68. }
  69. } else setTopInfo(obj)
  70. }
  71. }, [numNameChangeFu])
  72. // 获取详情
  73. const getInfoFu = useCallback(
  74. async (id2?: number) => {
  75. const res = await E1_APIgetInfo(id2 || id)
  76. if (res.code === 0) {
  77. const data = res.data
  78. setTopInfo(data)
  79. // 设置富文本
  80. ZRichTextRefQian.current?.ritxtShowFu(JSON.parse(data.authInfoRtf || '{}'))
  81. ZRichTextRefHou.current?.ritxtShowFu(JSON.parse(data.authResultRtf || '{}'))
  82. ZRichTextRefYuan.current?.ritxtShowFu(JSON.parse(data.reason || '{}'))
  83. ZRichTextRef.current?.ritxtShowFu(JSON.parse(data.rtf || '{}'))
  84. if (data.numName) numNameChangeFu(data.numName)
  85. }
  86. },
  87. [id, numNameChangeFu]
  88. )
  89. useEffect(() => {
  90. if (key === '1') creatFu()
  91. else getInfoFu()
  92. if (sollrDom.current) sollrDom.current.scrollTop = 0
  93. }, [creatFu, getInfoFu, key])
  94. const pageTitTxt = useMemo(() => {
  95. return Reflect.get(pageTitTxtObj, key)
  96. }, [key])
  97. const timeChange = useCallback(
  98. (e: any) => {
  99. setTopInfo({ ...topInfo, date: dayjs(e).format('YYYY-MM-DD') })
  100. },
  101. [topInfo]
  102. )
  103. // 上传附件的ref
  104. const filesRef = useRef<any>(null)
  105. // 事故前的ref
  106. const ZRichTextRefQian = useRef<any>(null)
  107. // 事故后的ref
  108. const ZRichTextRefHou = useRef<any>(null)
  109. // 事故原因及经过
  110. const ZRichTextRefYuan = useRef<any>(null)
  111. // 备注的ref
  112. const ZRichTextRef = useRef<any>(null)
  113. // 审批意见的ref
  114. const ZAuditRef = useRef<any>(null)
  115. // 审批的sta
  116. const [auditSta, setAuDitSta] = useState('')
  117. // 字段的校验
  118. const checkFu = useCallback(() => {
  119. if (!topInfo.date) {
  120. MessageFu.warning('请选择事故时间')
  121. return true
  122. }
  123. if (!topInfo.sonTypeName) {
  124. MessageFu.warning('请输入事故责任')
  125. return true
  126. }
  127. if (!topInfo.numName || !topInfo.goodsIds) {
  128. MessageFu.warning('请选择事故藏品')
  129. return true
  130. }
  131. }, [topInfo])
  132. // 新增的底部按钮点击
  133. const btnClickFu = useCallback(
  134. async (val: '草稿' | '创建' | '保存' | '审批') => {
  135. if (checkFu()) {
  136. if (sollrDom.current) sollrDom.current.scrollTop = 0
  137. return
  138. }
  139. if (val === '审批') {
  140. // console.log('审批信息富文本', rtf2)
  141. if (!auditSta) {
  142. if (sollrDom.current) sollrDom.current.scrollTop = 0
  143. return MessageFu.warning('请选择审批结果')
  144. }
  145. const rtf2 = ZAuditRef.current?.resData()
  146. const res = await E1_APIsaveAudit({
  147. orderId: topInfo.id,
  148. rtfOpinion: rtf2,
  149. status: auditSta === '同意' ? 1 : 2
  150. })
  151. if (res.code === 0) {
  152. MessageFu.success('审批成功')
  153. // 跳详情页
  154. history.push(`/accident_edit/4/${topInfo.id}`)
  155. }
  156. } else {
  157. // 多个富文本
  158. const rtfQian = ZRichTextRefQian.current?.fatherBtnOkFu() || { flag: true }
  159. const rtfHou = ZRichTextRefHou.current?.fatherBtnOkFu() || { flag: true }
  160. const rtfYuan = ZRichTextRefYuan.current?.fatherBtnOkFu() || { flag: true }
  161. const rtf1 = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
  162. // 上传附件
  163. const filesRes = filesRef.current.filesIdRes()
  164. const obj = {
  165. ...topInfo,
  166. authInfoRtf: JSON.stringify(rtfQian.val || ''),
  167. authResultRtf: JSON.stringify(rtfHou.val || ''),
  168. reason: JSON.stringify(rtfYuan.val || ''),
  169. rtf: JSON.stringify(rtf1.val || ''),
  170. fileIds: filesRes.join(',')
  171. }
  172. // console.log(123, obj)
  173. // if (1 + 1 === 2) return
  174. if (val === '草稿') {
  175. // 存草稿 当前页保存 不跳转
  176. const res = await E1_APIsaveDraft(obj)
  177. if (res.code === 0) {
  178. MessageFu.success('草稿保存成功')
  179. getInfoFu(topInfo.id)
  180. }
  181. } else {
  182. const res = val === '创建' ? await E1_APIsaveCreate(obj) : await E1_APIsaveApply(obj)
  183. if (res.code === 0) {
  184. MessageFu.success(`${val}成功`)
  185. // 跳到详情页
  186. history.push(`/accident_edit/4/${topInfo.id}`)
  187. }
  188. }
  189. }
  190. },
  191. [auditSta, checkFu, getInfoFu, topInfo]
  192. )
  193. // 查看的按钮创建-提交-撤回
  194. const lookBtnFu = useCallback(
  195. async (val: '创建' | '提交' | '撤回') => {
  196. // 多个富文本
  197. const rtfQian = ZRichTextRefQian.current?.fatherBtnOkFu() || { flag: true }
  198. const rtfHou = ZRichTextRefHou.current?.fatherBtnOkFu() || { flag: true }
  199. const rtfYuan = ZRichTextRefYuan.current?.fatherBtnOkFu() || { flag: true }
  200. const rtf1 = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
  201. // 上传附件
  202. const filesRes = filesRef.current.filesIdRes()
  203. const obj = {
  204. ...topInfo,
  205. authInfoRtf: JSON.stringify(rtfQian.val || ''),
  206. authResultRtf: JSON.stringify(rtfHou.val || ''),
  207. reason: JSON.stringify(rtfYuan.val || ''),
  208. rtf: JSON.stringify(rtf1.val || ''),
  209. fileIds: filesRes.join(',')
  210. }
  211. const res =
  212. val === '创建'
  213. ? await E1_APIsaveCreate(obj)
  214. : val === '提交'
  215. ? await E1_APIsaveApply(obj)
  216. : await E1_APIrevocation(id)
  217. if (res.code === 0) {
  218. if (sollrDom.current) sollrDom.current.scrollTop = 0
  219. MessageFu.success(val + '成功')
  220. getInfoFu()
  221. }
  222. },
  223. [getInfoFu, id, topInfo]
  224. )
  225. // 查看模式点击删除
  226. const delFu = useCallback(async () => {
  227. const res = await E1_APIdel(id)
  228. if (res.code === 0) {
  229. MessageFu.success('删除成功')
  230. history.push('/accident')
  231. }
  232. }, [id])
  233. // 查看模式点击审批 编辑
  234. const lookJumpFu = useCallback(
  235. (val: '审批' | '编辑') => {
  236. history.push(`/accident_edit/${val === '审批' ? 3 : 2}/${id}`)
  237. MessageFu.success(`已跳转至${val}页面`)
  238. },
  239. [id]
  240. )
  241. // 查看模式下的按钮
  242. const lookBtn = useMemo(() => {
  243. return (
  244. <>
  245. {btnFlagFu2(topInfo)['创建'] ? (
  246. <Button type='primary' onClick={() => lookBtnFu('创建')}>
  247. 创建
  248. </Button>
  249. ) : null}
  250. {btnFlagFu2(topInfo)['提交'] ? (
  251. <Button type='primary' onClick={() => lookBtnFu('提交')}>
  252. 提交
  253. </Button>
  254. ) : null}
  255. {btnFlagFu2(topInfo)['撤回'] ? (
  256. <MyPopconfirm
  257. txtK='撤回'
  258. onConfirm={() => lookBtnFu('撤回')}
  259. Dom={
  260. <Button type='primary' danger>
  261. 撤回
  262. </Button>
  263. }
  264. />
  265. ) : null}
  266. {btnFlagFu2(topInfo)['审批'] ? (
  267. <Button type='primary' onClick={() => lookJumpFu('审批')}>
  268. 审批
  269. </Button>
  270. ) : null}
  271. {btnFlagFu2(topInfo)['编辑'] ? (
  272. <Button type='primary' onClick={() => lookJumpFu('编辑')}>
  273. 编辑
  274. </Button>
  275. ) : null}
  276. {btnFlagFu2(topInfo)['重新提交'] ? (
  277. <Button type='primary' onClick={() => lookBtnFu('提交')}>
  278. 重新提交
  279. </Button>
  280. ) : null}
  281. {EXbtnFu(topInfo)}
  282. {btnFlagFu2(topInfo)['删除'] ? (
  283. <MyPopconfirm
  284. txtK='删除'
  285. onConfirm={() => delFu()}
  286. Dom={
  287. <Button type='primary' danger>
  288. 删除
  289. </Button>
  290. }
  291. />
  292. ) : null}
  293. <Button onClick={() => history.push('/accident')}>返回</Button>
  294. </>
  295. )
  296. }, [delFu, lookBtnFu, lookJumpFu, topInfo])
  297. // 申请记录
  298. const [auditsShow, setAuditsShow] = useState(false)
  299. return (
  300. <div className={styles.E1edit}>
  301. <div className='pageTitle'>事故登记-{pageTitTxt}</div>
  302. <div className='E1main' ref={sollrDom}>
  303. {['3'].includes(key) ? (
  304. <X3auditInfo
  305. dirCode='E1accident'
  306. myUrl='cms/goodsFile/upload'
  307. auditSta={auditSta}
  308. auditStaFu={val => setAuDitSta(val)}
  309. ref={ZAuditRef}
  310. />
  311. ) : null}
  312. {/* 表单字段、附件等 */}
  313. <div className='E1Tit'>
  314. 申请信息
  315. {key === '1' ? null : (
  316. <Button type='dashed'>{Reflect.get(statusObj, topInfo.status)}</Button>
  317. )}
  318. </div>
  319. <div className='E1rowAll'>
  320. <div className='E1row'>
  321. <div className='E1rowll'>申请类型:</div>
  322. <div className='E1rowrr'>{topInfo.name}</div>
  323. </div>
  324. <div className='E1row'>
  325. <div className='E1rowll'>
  326. <span> * </span>事故时间:
  327. </div>
  328. <div className='E1rowrr'>
  329. <DatePicker
  330. disabled={['3', '4'].includes(key)}
  331. allowClear={false}
  332. value={topInfo.date ? dayjs(topInfo.date) : null}
  333. onChange={timeChange}
  334. />
  335. </div>
  336. </div>
  337. <div className='E1row'>
  338. <div className='E1rowll'>
  339. <span> * </span>事故责任:
  340. </div>
  341. <div className='E1rowrr'>
  342. <Input
  343. value={topInfo.sonTypeName}
  344. onChange={e => setTopInfo({ ...topInfo, sonTypeName: e.target.value.trim() })}
  345. readOnly={['3', '4'].includes(key)}
  346. placeholder='请输入内容'
  347. maxLength={30}
  348. showCount
  349. />
  350. </div>
  351. </div>
  352. <div className='E1row'>
  353. <div className='E1rowll'>
  354. <span> * </span>事故藏品:
  355. </div>
  356. <div className='E1rowrr'>
  357. <Select
  358. disabled={['3', '4'].includes(key)}
  359. allowClear={false}
  360. placeholder='请选择编号类型'
  361. style={{ width: 150 }}
  362. value={topInfo.numName ? topInfo.numName : null}
  363. onChange={e => {
  364. setTopInfo({ ...topInfo, numName: e, goodsIds: '' })
  365. numNameChangeFu(e)
  366. }}
  367. options={selectObj['藏品编号类型']}
  368. />
  369. <Select
  370. disabled={['3', '4'].includes(key) || !topInfo.numName}
  371. placeholder={!topInfo.numName ? '请先选择编号类型' : '请输入藏品编号或藏品名称'}
  372. showSearch
  373. filterOption={(input, option) => {
  374. const txt = option!.label + option!.num
  375. return txt.toLowerCase().includes(input.toLowerCase())
  376. }}
  377. options={goodsArr}
  378. // fieldNames={{ label: 'num', value: 'num' }}
  379. allowClear={false}
  380. value={topInfo.goodsIds || null}
  381. onChange={e => setTopInfo({ ...topInfo, goodsIds: e ? e : '' })}
  382. />
  383. </div>
  384. </div>
  385. <div className='E1row E1rowFull'>
  386. <div className='E1rowll'>
  387. 事故前&emsp;
  388. <br />
  389. 藏品状态:
  390. </div>
  391. <div className='E1rowrr'>
  392. <ZRichTexts
  393. check={false}
  394. dirCode='E1accident'
  395. myUrl='cms/goodsFile/upload'
  396. isLook={['3', '4'].includes(key)}
  397. ref={ZRichTextRefQian}
  398. isOne={true}
  399. upAudioBtnNone={true}
  400. />
  401. </div>
  402. </div>
  403. <div className='E1row E1rowFull'>
  404. <div className='E1rowll'>
  405. 事故后&emsp;
  406. <br />
  407. 藏品现状:
  408. </div>
  409. <div className='E1rowrr'>
  410. <ZRichTexts
  411. check={false}
  412. dirCode='E1accident'
  413. myUrl='cms/goodsFile/upload'
  414. isLook={['3', '4'].includes(key)}
  415. ref={ZRichTextRefHou}
  416. isOne={true}
  417. upAudioBtnNone={true}
  418. />
  419. </div>
  420. </div>
  421. <div className='E1row E1rowFull'>
  422. <div className='E1rowll'>
  423. 事故原因&emsp;
  424. <br />
  425. 及经过:
  426. </div>
  427. <div className='E1rowrr'>
  428. <ZRichTexts
  429. check={false}
  430. dirCode='E1accident'
  431. myUrl='cms/goodsFile/upload'
  432. isLook={['3', '4'].includes(key)}
  433. ref={ZRichTextRefYuan}
  434. isOne={true}
  435. upAudioBtnNone={true}
  436. />
  437. </div>
  438. </div>
  439. <div className='E1row E1row2'>
  440. <div className='E1rowll'>附件:</div>
  441. <div className='E1rowrr'>
  442. <Z3upFiles
  443. max={10}
  444. isLook={['3', '4'].includes(key)}
  445. ref={filesRef}
  446. fileCheck={false}
  447. dirCode='E1accident'
  448. myUrl='cms/orderPreserveAccident/upload'
  449. lookData={topInfo.files || []}
  450. size={500}
  451. fromData={{ moduleId: topInfo.id }}
  452. />
  453. </div>
  454. </div>
  455. <div className='E1row'>
  456. <div className='E1rowll'>鉴定人:</div>
  457. <div className='E1rowrr'>
  458. <Input
  459. value={topInfo.authUser}
  460. onChange={e => setTopInfo({ ...topInfo, authUser: e.target.value.trim() })}
  461. readOnly={['3', '4'].includes(key)}
  462. placeholder='请输入内容'
  463. maxLength={30}
  464. showCount
  465. />
  466. </div>
  467. </div>
  468. <div className='E1row E1rowFull'>
  469. <div className='E1rowll'>备注:</div>
  470. <div className='E1rowrr'>
  471. <ZRichTexts
  472. check={false}
  473. dirCode='E1accident'
  474. myUrl='cms/goodsFile/upload'
  475. isLook={['3', '4'].includes(key)}
  476. ref={ZRichTextRef}
  477. isOne={true}
  478. upAudioBtnNone={true}
  479. />
  480. </div>
  481. </div>
  482. </div>
  483. {/* 申请流程 */}
  484. {auditsShow ? (
  485. <ZflowTable tableArr={topInfo.audits || []} closeFu={() => setAuditsShow(false)} />
  486. ) : null}
  487. {/* 附件归档 */}
  488. {topInfo.status === 4 ? (
  489. <ZupFileTable
  490. listTemp={topInfo.filing || []}
  491. dirCode='E1accident'
  492. myUrl='cms/orderPreserveAccident/upload'
  493. fromData={{ moduleId: topInfo.id }}
  494. />
  495. ) : null}
  496. </div>
  497. {/* 底部按钮 */}
  498. <div className='E1btn'>
  499. {['3', '4'].includes(key) && topInfo.audits && topInfo.audits.length ? (
  500. <Button type='primary' onClick={() => setAuditsShow(true)}>
  501. 申请记录
  502. </Button>
  503. ) : null}
  504. {key === '4' ? (
  505. lookBtn
  506. ) : (
  507. <>
  508. {key === '3' ? (
  509. <Button type='primary' onClick={() => btnClickFu('审批')}>
  510. 审批
  511. </Button>
  512. ) : (
  513. <Button type='primary' onClick={() => btnClickFu(key === '1' ? '创建' : '保存')}>
  514. {key === '1' ? '创建' : '保存'}
  515. </Button>
  516. )}
  517. {key === '1' ? (
  518. <Button type='primary' onClick={() => btnClickFu('草稿')}>
  519. 存草稿
  520. </Button>
  521. ) : null}
  522. <MyPopconfirm txtK='取消' onConfirm={() => history.push('/accident')} />
  523. </>
  524. )}
  525. </div>
  526. </div>
  527. )
  528. }
  529. const MemoE1edit = React.memo(E1edit)
  530. export default MemoE1edit