index.tsx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
  2. import styles from './index.module.scss'
  3. import { useParams } from 'react-router-dom'
  4. import { Button, Cascader, Checkbox, Input } from 'antd'
  5. import ZRichTexts from '@/components/ZRichTexts'
  6. import MyPopconfirm from '@/components/MyPopconfirm'
  7. import history, { btnFlagFu2, cascaderObjFu, openGoodsInfoFu } from '@/utils/history'
  8. import { MessageFu } from '@/utils/message'
  9. import MyTable from '@/components/MyTable'
  10. import classNames from 'classnames'
  11. import { D4goodsTableC, statusObj } from '@/utils/tableData'
  12. import ZGaddNow from '@/components/ZGaddNow'
  13. import X3auditInfo from '@/pages/X_stock/X3auditInfo'
  14. import ZflowTable from '@/components/ZflowTable'
  15. import { C1GoodType } from '@/pages/A3_ledger/C1ledger/type'
  16. import { EXbtnFu } from '@/utils/EXBtn'
  17. import {
  18. C21_APIcreate,
  19. C21_APIdel,
  20. C21_APIgetInfo,
  21. C21_APIsaveApply,
  22. C21_APIsaveAudit,
  23. C21_APIsaveCreate,
  24. C21_APIsaveDraft
  25. } from '@/store/action/C21wealth'
  26. import { MEDIA_TYPES } from '../constants'
  27. import { IC21Detail } from '../types'
  28. export const pageTitTxtObj = {
  29. 1: '新增',
  30. 2: '编辑',
  31. 3: '审批',
  32. 4: '查看'
  33. }
  34. function C21edit() {
  35. const { key, id } = useParams<any>()
  36. // key:1 新增 2编辑 3审批 4查看
  37. // 滚到顶部
  38. const sollrDom = useRef<HTMLDivElement>(null)
  39. // 顶部数据
  40. const [topInfo, setTopInfo] = useState({
  41. sonTypeName: '',
  42. effect: ''
  43. } as IC21Detail)
  44. // 藏品清单快照数据
  45. const [snaps, setSnaps] = useState<C1GoodType[]>([])
  46. const delSnapIdsRef = useRef<number[]>([])
  47. const snapsID2ref = useRef<{ goodsId: number; id: number }[]>([])
  48. // 创建订单
  49. const creatFu = useCallback(async () => {
  50. const res = await C21_APIcreate()
  51. if (res.code === 0) {
  52. setTopInfo({ ...res.data, sonTypeName: MEDIA_TYPES.map(i => i.value).join(',') })
  53. }
  54. }, [])
  55. // 获取详情
  56. const getInfoFu = useCallback(async () => {
  57. const res = await C21_APIgetInfo(id)
  58. if (res.code === 0) {
  59. setTopInfo(res.data)
  60. // 设置富文本
  61. ZRichTextRef.current?.ritxtShowFu(JSON.parse(res.data.rtf || '{}'))
  62. // 藏品清单快照信息id对比
  63. const arrTemp: any = []
  64. const snapsTemp = res.data.snaps || []
  65. snapsTemp.forEach((v: any) => {
  66. snapsID2ref.current.push({ goodsId: v.goodsId, id: v.id })
  67. const obj = JSON.parse(v.snap || '{}')
  68. if (obj.id) obj.id2 = v.id
  69. arrTemp.push(obj)
  70. })
  71. setSnaps(arrTemp)
  72. }
  73. }, [id])
  74. useEffect(() => {
  75. if (key === '1') creatFu()
  76. else getInfoFu()
  77. if (sollrDom.current) sollrDom.current.scrollTop = 0
  78. }, [creatFu, getInfoFu, key])
  79. // 富文本的ref
  80. const ZRichTextRef = useRef<any>(null)
  81. // 审批意见的ref
  82. const ZAuditRef = useRef<any>(null)
  83. const pageTitTxt = useMemo(() => {
  84. return Reflect.get(pageTitTxtObj, key)
  85. }, [key])
  86. const checkDataFu = useCallback(() => {
  87. if (!topInfo.effect) {
  88. MessageFu.warning('请选择使用途径')
  89. return true
  90. }
  91. if (!topInfo.sonTypeName) {
  92. MessageFu.warning('请选择资源类型')
  93. return true
  94. }
  95. return false
  96. }, [topInfo])
  97. // 审批的sta
  98. const [auditSta, setAuDitSta] = useState('')
  99. // 新增的底部按钮点击
  100. const btnClickFu = useCallback(
  101. async (val: '草稿' | '创建' | '保存' | '审批') => {
  102. if (checkDataFu()) return
  103. if (val !== '草稿') {
  104. if (snaps.length === 0) return MessageFu.warning('请添加藏品')
  105. }
  106. if (val === '审批') {
  107. // console.log('审批信息富文本', rtf2)
  108. if (!auditSta) {
  109. if (sollrDom.current) sollrDom.current.scrollTop = 0
  110. return MessageFu.warning('请选择审批结果')
  111. }
  112. const rtf2 = ZAuditRef.current?.resData()
  113. const res = await C21_APIsaveAudit({
  114. orderId: topInfo.id,
  115. rtfOpinion: rtf2,
  116. status: auditSta === '同意' ? 1 : 2
  117. })
  118. if (res.code === 0) {
  119. MessageFu.success('审批成功')
  120. // 跳详情页
  121. history.push(`/wealth_edit/4/${topInfo.id}`)
  122. }
  123. } else {
  124. const rtf1 = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
  125. // console.log('申请信息富文本', JSON.stringify(rtf1.val || ''))
  126. const obj = {
  127. ...topInfo,
  128. rtf: JSON.stringify(rtf1.val || ''),
  129. goodsIds: snaps.map(v => v.id).join(','),
  130. delSnapIds: delSnapIdsRef.current.length ? delSnapIdsRef.current : '',
  131. snaps: snaps.map(v => ({
  132. goodsId: v.id,
  133. id: v.id2 ? v.id2 : null,
  134. orderId: topInfo.id,
  135. snap: JSON.stringify(v)
  136. }))
  137. }
  138. // console.log(123, obj)
  139. // if (1 + 1 === 2) return
  140. if (val === '草稿') {
  141. // 存草稿 当前页保存 不跳转
  142. const res = await C21_APIsaveDraft(obj)
  143. if (res.code === 0) {
  144. MessageFu.success('草稿保存成功')
  145. }
  146. } else {
  147. const res = val === '创建' ? await C21_APIsaveCreate(obj) : await C21_APIsaveApply(obj)
  148. if (res.code === 0) {
  149. MessageFu.success(`${val}成功`)
  150. // 跳到详情页
  151. history.push(`/wealth_edit/4/${topInfo.id}`)
  152. }
  153. }
  154. }
  155. },
  156. [auditSta, checkDataFu, topInfo, snaps]
  157. )
  158. // 打开侧边栏
  159. const [cathet, setCathet] = useState(0)
  160. const startBtn = useMemo(() => {
  161. return [
  162. {
  163. title: '藏品编号',
  164. render: (item: C1GoodType) => {
  165. return (
  166. <span
  167. onClick={() => setCathet(item.id)}
  168. className={classNames('D1GtNum', item.id === cathet ? 'D1GtNumAc' : '')}
  169. >
  170. {item.num}
  171. </span>
  172. )
  173. }
  174. }
  175. ]
  176. }, [cathet])
  177. const tableLastBtn = useMemo(() => {
  178. return [
  179. {
  180. title: '操作',
  181. render: (item: C1GoodType) => {
  182. return (
  183. <>
  184. <Button size='small' type='text' onClick={() => openGoodsInfoFu(item.id)}>
  185. 查看
  186. </Button>
  187. {['3', '4'].includes(key) ? null : (
  188. <MyPopconfirm
  189. txtK='删除'
  190. onConfirm={() =>
  191. setTopInfo({
  192. ...topInfo,
  193. goods: topInfo.goods.filter(v => v.id !== item.id)
  194. })
  195. }
  196. />
  197. )}
  198. </>
  199. )
  200. }
  201. }
  202. ]
  203. }, [key, topInfo])
  204. // 点击新增
  205. const [nowSta, setNowSta] = useState({ key: '', id: '' })
  206. // 查看的按钮创建-提交-撤回
  207. const lookBtnFu = useCallback(
  208. async (val: '创建' | '提交') => {
  209. const rtf1 = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
  210. // console.log('申请信息富文本', JSON.stringify(rtf1.val || ''))
  211. const obj = {
  212. ...topInfo,
  213. rtf: JSON.stringify(rtf1.val || ''),
  214. goodsIds: snaps.map(v => v.id).join(','),
  215. delSnapIds: delSnapIdsRef.current.length ? delSnapIdsRef.current : '',
  216. snaps: snaps.map(v => ({
  217. goodsId: v.id,
  218. id: v.id2 ? v.id2 : null,
  219. orderId: topInfo.id,
  220. snap: JSON.stringify(v)
  221. }))
  222. }
  223. const res = val === '创建' ? await C21_APIsaveCreate(obj) : await C21_APIsaveApply(obj)
  224. if (res.code === 0) {
  225. if (sollrDom.current) sollrDom.current.scrollTop = 0
  226. MessageFu.success(val + '成功')
  227. getInfoFu()
  228. }
  229. },
  230. [getInfoFu, topInfo, snaps]
  231. )
  232. // 查看模式点击删除
  233. const delFu = useCallback(async () => {
  234. const res = await C21_APIdel(id)
  235. if (res.code === 0) {
  236. MessageFu.success('删除成功')
  237. history.push('/wealth')
  238. }
  239. }, [id])
  240. // 查看模式点击审批 编辑
  241. const lookJumpFu = useCallback(
  242. (val: '审批' | '编辑') => {
  243. history.push(`/wealth_edit/${val === '审批' ? 3 : 2}/${id}`)
  244. MessageFu.success(`已跳转至${val}页面`)
  245. },
  246. [id]
  247. )
  248. // 查看模式下的按钮
  249. const lookBtn = useMemo(() => {
  250. return (
  251. <>
  252. {btnFlagFu2(topInfo)['创建'] ? (
  253. <Button type='primary' onClick={() => lookBtnFu('创建')}>
  254. 创建
  255. </Button>
  256. ) : null}
  257. {btnFlagFu2(topInfo)['提交'] ? (
  258. <Button type='primary' onClick={() => lookBtnFu('提交')}>
  259. 提交
  260. </Button>
  261. ) : null}
  262. {btnFlagFu2(topInfo)['审批'] ? (
  263. <Button type='primary' onClick={() => lookJumpFu('审批')}>
  264. 审批
  265. </Button>
  266. ) : null}
  267. {btnFlagFu2(topInfo)['编辑'] ? (
  268. <Button type='primary' onClick={() => lookJumpFu('编辑')}>
  269. 编辑
  270. </Button>
  271. ) : null}
  272. {btnFlagFu2(topInfo)['重新提交'] ? (
  273. <Button type='primary' onClick={() => lookBtnFu('提交')}>
  274. 重新提交
  275. </Button>
  276. ) : null}
  277. {EXbtnFu(topInfo)}
  278. {btnFlagFu2(topInfo)['删除'] ? (
  279. <MyPopconfirm
  280. txtK='删除'
  281. onConfirm={() => delFu()}
  282. Dom={
  283. <Button type='primary' danger>
  284. 删除
  285. </Button>
  286. }
  287. />
  288. ) : null}
  289. <Button onClick={() => history.push('/wealth')}>返回</Button>
  290. </>
  291. )
  292. }, [delFu, lookBtnFu, lookJumpFu, topInfo])
  293. // 申请记录
  294. const [auditsShow, setAuditsShow] = useState(false)
  295. return (
  296. <div className={styles.C21edit}>
  297. <div className='pageTitle'>资源使用-{pageTitTxt}</div>
  298. <div className='D4main' ref={sollrDom}>
  299. {['3'].includes(key) ? (
  300. <X3auditInfo
  301. dirCode='D4wealth'
  302. myUrl='cms/orderIn/upload'
  303. auditSta={auditSta}
  304. auditStaFu={val => setAuDitSta(val)}
  305. ref={ZAuditRef}
  306. />
  307. ) : null}
  308. {/* 表单字段、附件等 */}
  309. <div className='D4Tit'>
  310. 申请信息
  311. {key === '1' ? null : (
  312. <Button type='dashed'>{Reflect.get(statusObj, topInfo.status)}</Button>
  313. )}
  314. </div>
  315. <div className='D4rowAll'>
  316. <div className='D4row'>
  317. <div className='D4rowll'>业务单号:</div>
  318. <div className='D4rowrr'>{topInfo.num}</div>
  319. </div>
  320. <div className='D4row'>
  321. <div className='D4rowll'>业务名称:</div>
  322. <div className='D4rowrr'>{topInfo.name}</div>
  323. </div>
  324. <div className='D4row'>
  325. <div className='D4rowll'>发起人:</div>
  326. <div className='D4rowrr'>{topInfo.creatorName}</div>
  327. </div>
  328. <div className='D4row'>
  329. <div className='D4rowll'>发起部门:</div>
  330. <div className='D4rowrr'>{topInfo.deptName}</div>
  331. </div>
  332. <div className='D4row'>
  333. <div className='D4rowll'>
  334. <span> * </span>使用途径:
  335. </div>
  336. <div className='D4rowrr'>
  337. {topInfo.num && (
  338. <Cascader
  339. defaultValue={topInfo.effect.split(',')}
  340. disabled={['3', '4'].includes(key)}
  341. options={cascaderObjFu()['附件用途']}
  342. onChange={e => setTopInfo({ ...topInfo, effect: e ? e.join(',') : '' })}
  343. placeholder='请选择'
  344. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  345. />
  346. )}
  347. </div>
  348. </div>
  349. <div className='D4row'>
  350. <div className='D4rowll'>原因事由:</div>
  351. <div className='D4rowrr'>
  352. <Input
  353. value={topInfo.reason}
  354. onChange={e => setTopInfo({ ...topInfo, reason: e.target.value })}
  355. readOnly={['3', '4'].includes(key)}
  356. placeholder='请输入内容'
  357. maxLength={30}
  358. showCount
  359. />
  360. </div>
  361. </div>
  362. <div className='D4row D4rowFull' style={{ margin: '0 0 20px' }}>
  363. <div className='D4rowll'>
  364. <span> * </span>资源类型:
  365. </div>
  366. <div className='D4rowrr'>
  367. {topInfo.num && (
  368. <Checkbox.Group
  369. defaultValue={topInfo.sonTypeName.split(',')}
  370. disabled={['3', '4'].includes(key)}
  371. options={MEDIA_TYPES}
  372. onChange={e => setTopInfo({ ...topInfo, sonTypeName: e.join(',') })}
  373. />
  374. )}
  375. </div>
  376. </div>
  377. <div className='D4row D4rowFull' style={{ margin: 0 }}>
  378. <div className='D4rowll'>备注:</div>
  379. <div className='D4rowrr'>
  380. <ZRichTexts
  381. check={false}
  382. dirCode='wealth'
  383. myUrl='cms/orderIn/upload'
  384. isLook={['3', '4'].includes(key)}
  385. ref={ZRichTextRef}
  386. isOne={true}
  387. upAudioBtnNone={true}
  388. />
  389. </div>
  390. </div>
  391. </div>
  392. {/* 藏品清单 */}
  393. <div className='D4googsBox'>
  394. <div className='D4Tit2'>
  395. <div className='D4Tit2ll'>藏品清单</div>
  396. <div className='D4Tit2rr'>
  397. {['3', '4'].includes(key) ? null : (
  398. <>
  399. <Button
  400. type='primary'
  401. onClick={() => {
  402. setNowSta({ key: '5', id: 'cms/orderZy/goods/getList' })
  403. }}
  404. >
  405. 新增
  406. </Button>
  407. </>
  408. )}
  409. </div>
  410. </div>
  411. {/* 表格 */}
  412. <MyTable
  413. list={snaps}
  414. columnsTemp={D4goodsTableC}
  415. startBtn={startBtn}
  416. lastBtn={tableLastBtn}
  417. pagingInfo={false}
  418. />
  419. </div>
  420. {/* 申请流程 */}
  421. {auditsShow ? (
  422. <ZflowTable tableArr={topInfo.audits || []} closeFu={() => setAuditsShow(false)} />
  423. ) : null}
  424. </div>
  425. {/* 底部按钮 */}
  426. <div className='D4btn'>
  427. {['3', '4'].includes(key) && topInfo.audits && topInfo.audits.length ? (
  428. <Button type='primary' onClick={() => setAuditsShow(true)}>
  429. 申请记录
  430. </Button>
  431. ) : null}
  432. {key === '4' ? (
  433. lookBtn
  434. ) : (
  435. <>
  436. {key === '3' ? (
  437. <Button type='primary' onClick={() => btnClickFu('审批')}>
  438. 审批
  439. </Button>
  440. ) : (
  441. <Button type='primary' onClick={() => btnClickFu(key === '1' ? '创建' : '保存')}>
  442. {key === '1' ? '创建' : '保存'}
  443. </Button>
  444. )}
  445. {key === '1' ? (
  446. <Button type='primary' onClick={() => btnClickFu('草稿')}>
  447. 存草稿
  448. </Button>
  449. ) : null}
  450. <MyPopconfirm txtK='取消' onConfirm={() => history.push('/wealth')} />
  451. </>
  452. )}
  453. </div>
  454. {/* 新增弹窗 */}
  455. {nowSta.id ? (
  456. <ZGaddNow
  457. httpType='get'
  458. nowSta={nowSta}
  459. closeFu={() => setNowSta({ key: '', id: '' })}
  460. dataResFu={data => {
  461. const dataTemp = [...data]
  462. dataTemp.forEach(v => {
  463. // id2表示的是自己这条数据的id id才是goodsId
  464. const obj = snapsID2ref.current.find(c => c.goodsId === v.id)
  465. if (obj) v.id2 = obj.id
  466. })
  467. setSnaps(dataTemp)
  468. }}
  469. oldCheckArr={snaps}
  470. />
  471. ) : null}
  472. </div>
  473. )
  474. }
  475. const MemoC21edit = React.memo(C21edit)
  476. export default MemoC21edit