index.tsx 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
  2. import styles from './index.module.scss'
  3. import { Button, Cascader, DatePicker, Form, FormInstance, Input, InputNumber, Select } from 'antd'
  4. import MyPopconfirm from '@/components/MyPopconfirm'
  5. import TextArea from 'antd/es/input/TextArea'
  6. import ZRichTexts from '@/components/ZRichTexts'
  7. import MyTable from '@/components/MyTable'
  8. import { Y33tableC } from '@/utils/tableData'
  9. import ImageLazy from '@/components/ImageLazy'
  10. import YtableVideo from '@/components/YtableVideo'
  11. import { selectObj } from '@/utils/select'
  12. import dayjs from 'dayjs'
  13. import { getTokenInfo } from '@/utils/storage'
  14. import Z3upFiles from '@/components/Z3upFiles'
  15. import { GoodFileType } from './type'
  16. import { baseURL } from '@/utils/http'
  17. import { fileImgArr, fileVideoArr } from '@/store/action/layout'
  18. import { API_C2dels } from '@/store/action/C2files'
  19. import { API_goodsAdd, API_goodsInfo } from '@/store/action/C1ledger'
  20. import { C1GoodType } from '@/pages/A3_ledger/C1ledger/type'
  21. import { MessageFu } from '@/utils/message'
  22. import history, { cascaderObjFu } from '@/utils/history'
  23. import ZGaddNow from '@/components/ZGaddNow'
  24. // 级联的数据转换成字符串
  25. export const cascaderChArr = [
  26. 'dictType',
  27. 'dictAge',
  28. 'pcsUnit',
  29. 'dictTexture1',
  30. 'dictTexture2',
  31. 'dictTexture3',
  32. 'dictTorn',
  33. 'sizeUnit',
  34. 'qualityDictScope',
  35. 'qualityUnit',
  36. 'inDictDateScope',
  37. 'source',
  38. 'dictHouse1',
  39. 'dictHouse2',
  40. // 其他模块有的级联字段
  41. 'dictAgeFirst'
  42. ]
  43. // 下拉框为空的时候转变成null
  44. export const addZiSelectChArr = ['numName', 'dictLevel', 'accountType']
  45. type Props = {
  46. closeFu: () => void
  47. nowSta: { key: string; id: string }
  48. isEdit: boolean //藏品编辑模块
  49. editSnap?: C1GoodType //藏品模块属于新增还是编辑
  50. succFu: (
  51. obj: C1GoodType,
  52. type: '新增' | '编辑',
  53. sta: '存草稿' | '提交',
  54. flieNew?: GoodFileType[],
  55. fileOld?: GoodFileType[],
  56. oldInfo?: C1GoodType
  57. ) => void
  58. }
  59. function AddGoods({ nowSta, closeFu, succFu, isEdit, editSnap }: Props) {
  60. // 制档日期 / 制档人
  61. const [txtArr, setTxtArr] = useState([getTokenInfo().user.realName, dayjs().format('YYYY-MM-DD')])
  62. // 藏品编辑模块用来对比
  63. const objOld = useRef<any>({})
  64. // 编辑进来获取详情
  65. const getInfo = useCallback(
  66. async (id: number) => {
  67. const res = await API_goodsInfo(id)
  68. if (res.code === 0) {
  69. // 藏品编辑信息保存
  70. objOld.current = { ...res.data }
  71. // dateMaking inGoodsDate 2个日期需要格式处理一下
  72. const obj = editSnap && editSnap.id ? { ...editSnap } : { ...res.data }
  73. if (obj.dateMaking) obj.dateMaking = dayjs(obj.dateMaking)
  74. // if (obj.inGoodsDate) obj.inGoodsDate = dayjs(obj.inGoodsDate)
  75. setTxtArr([obj.creatorName, dayjs(obj.createTime).format('YYYY-MM-DD')])
  76. cascaderChArr.forEach(v => {
  77. if (obj[v]) obj[v] = obj[v].split(',')
  78. })
  79. addZiSelectChArr.forEach(v => {
  80. if (!obj[v]) obj[v] = null
  81. })
  82. FormBoxRef.current?.setFieldsValue(obj)
  83. // 设置封面图
  84. // ZupThumbRef.current?.setFileComFileFu({
  85. // fileName: '',
  86. // filePath: obj.thumbPc,
  87. // thumb: obj.thumb
  88. // })
  89. // 设置富文本
  90. if (obj.rtf) ZRichTextRef.current?.ritxtShowFu(JSON.parse(obj.rtf))
  91. // 设置附件
  92. setTable(obj.file || [])
  93. }
  94. },
  95. [editSnap]
  96. )
  97. useEffect(() => {
  98. if (nowSta.id !== 'null') {
  99. getInfo(Number(nowSta.id))
  100. }
  101. }, [getInfo, nowSta.id])
  102. // 设置表单ref
  103. const FormBoxRef = useRef<FormInstance>(null)
  104. // 年代是否选择了其他
  105. const [ageAc, setAgeAc] = useState(false)
  106. // 封面图的ref
  107. // const ZupThumbRef = useRef<any>(null)
  108. // 富文本的ref
  109. const ZRichTextRef = useRef<any>(null)
  110. // 上传附件的ref
  111. const filesRef = useRef<any>(null)
  112. // 附件表格
  113. const [table, setTable] = useState<GoodFileType[]>([])
  114. // 附件删除记录id
  115. const fileDelIdArr = useRef<number[]>([])
  116. const tableFu = useCallback(
  117. (key: 'type' | 'effect', id: number, val: any) => {
  118. setTable(
  119. table.map(v => ({
  120. ...v,
  121. [key]: id === v.id ? val : v[key]
  122. }))
  123. )
  124. },
  125. [table]
  126. )
  127. // 附件类型和附件用途是否禁用
  128. const disabledSelect = useCallback(
  129. (id: number) => {
  130. let flag = false
  131. if (isEdit) {
  132. if (objOld.current && objOld.current.file && objOld.current.file.length) {
  133. const oldFileIds: number[] = objOld.current.file.map((v: any) => v.id)
  134. if (oldFileIds.includes(id)) flag = true
  135. }
  136. }
  137. return flag
  138. },
  139. [isEdit]
  140. )
  141. // 相关附件的操作
  142. const startBtn = useMemo(() => {
  143. return [
  144. {
  145. width: 100,
  146. title: '缩略图/视频',
  147. render: (item: GoodFileType) => {
  148. const fileNameArr = item.fileName.split('.')
  149. const fileNameLast = fileNameArr[fileNameArr.length - 1]
  150. return fileImgArr.includes(fileNameLast) ? (
  151. <div className='tableImgAuto'>
  152. <ImageLazy width={60} height={60} srcBig={item.filePath} src={item.thumb} />
  153. </div>
  154. ) : fileVideoArr.includes(fileNameLast) ? (
  155. <YtableVideo src={item.filePath} />
  156. ) : (
  157. ' - '
  158. )
  159. }
  160. },
  161. {
  162. title: '附件类型',
  163. render: (item: GoodFileType) => (
  164. <Select
  165. disabled={disabledSelect(item.id)}
  166. style={{ width: 120 }}
  167. placeholder='请选择'
  168. value={item.type}
  169. onChange={e => tableFu('type', item.id, e)}
  170. options={selectObj['附件类型']}
  171. />
  172. )
  173. },
  174. {
  175. title: '附件用途',
  176. render: (item: GoodFileType) => (
  177. <Cascader
  178. disabled={disabledSelect(item.id)}
  179. options={cascaderObjFu()['附件用途']}
  180. value={item.effect ? item.effect.split(',') : []}
  181. onChange={e => tableFu('effect', item.id, e ? e.join(',') : '')}
  182. placeholder='请选择'
  183. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  184. />
  185. )
  186. }
  187. ]
  188. }, [disabledSelect, tableFu])
  189. const tableLastBtn = useMemo(() => {
  190. return [
  191. {
  192. width: 120,
  193. title: '操作',
  194. render: (item: GoodFileType) => {
  195. return (
  196. <>
  197. <Button size='small' type='text'>
  198. <a href={baseURL + item.filePath} download target='_blank' rel='noreferrer'>
  199. 下载
  200. </a>
  201. </Button>
  202. <MyPopconfirm
  203. txtK='删除'
  204. onConfirm={() => {
  205. setTable(table.filter(v => v.id !== item.id))
  206. fileDelIdArr.current.push(item.id)
  207. }}
  208. />
  209. </>
  210. )
  211. }
  212. }
  213. ]
  214. }, [table])
  215. // 没有通过校验
  216. const onFinishFailed = useCallback((info: any) => {
  217. const values = info.values || {}
  218. const errArr = info.errorFields
  219. if (errArr.some((v: any) => v.name.includes('inGoodsDate'))) {
  220. setTabTxt('附属信息')
  221. MessageFu.warning('请输入正确的入藏日期格式')
  222. } else if (!values.qualityDictScope || !values.source) {
  223. setTabTxt('附属信息')
  224. MessageFu.warning('请完善附属信息必填字段')
  225. } else {
  226. setTabTxt('基本信息')
  227. MessageFu.warning('请完善基本信息必填字段')
  228. }
  229. }, [])
  230. // 通过校验点击确定
  231. const onFinish = useCallback(
  232. async (values: any) => {
  233. // 封面图
  234. // const coverUrl1 = ZupThumbRef.current?.fileComFileResFu()
  235. // 富文本
  236. const rtf = ZRichTextRef.current?.fatherBtnOkFu() || { flag: true }
  237. // 附件
  238. let fileIds = ''
  239. let fileSet: any = null
  240. if (table.length) {
  241. fileIds = table.map(v => v.id).join(',')
  242. fileSet = table.map(v => ({
  243. effect: v.effect,
  244. id: v.id,
  245. type: v.type
  246. }))
  247. }
  248. // 2个日期的格式处理
  249. // let inGoodsDate = ''
  250. // if (values.inGoodsDate) inGoodsDate = dayjs(values.inGoodsDate).format('YYYY-MM-DD')
  251. let dateMaking = ''
  252. if (values.dateMaking) dateMaking = dayjs(values.dateMaking).format('YYYY-MM-DD')
  253. // 默认以第一个附件为img的作为封面图
  254. const imgArr = table.filter(v => {
  255. const txtArr = v.fileName.split('.')
  256. const txt = txtArr[txtArr.length - 1]
  257. return v.type === 'img' && fileImgArr.includes(txt)
  258. })
  259. let thumb = ''
  260. let thumbPc = ''
  261. if (imgArr && imgArr.length) {
  262. thumb = imgArr[0].thumb
  263. thumbPc = imgArr[0].filePath
  264. }
  265. let idRes = nowSta.id === 'null' ? null : Number(nowSta.id)
  266. if (selectArr.current.length && selectArr.current[0].id) idRes = selectArr.current[0].id
  267. const obj = {
  268. ...values,
  269. thumb,
  270. thumbPc,
  271. rtf: JSON.stringify(rtf.val || ''),
  272. fileIds,
  273. fileSet,
  274. // inGoodsDate,
  275. dateMaking,
  276. id: idRes
  277. }
  278. for (const k in obj) {
  279. if (obj[k] === null || obj[k] === undefined) obj[k] = ''
  280. }
  281. // 级联的数据转换成字符串
  282. cascaderChArr.forEach(v => {
  283. if (values[v]) obj[v] = values[v].join(',')
  284. })
  285. // if (1 + 1 === 2) {
  286. // console.log(123, obj)
  287. // return
  288. // }
  289. if (isEdit) {
  290. // 藏品编辑模块
  291. let flag = true
  292. // fileIds 要特别处理
  293. const fileNew = table.map(v => v.id).join(',')
  294. const fileOld = (objOld.current.file || []).map((v: any) => v.id).join(',')
  295. if (fileNew !== fileOld) flag = false
  296. // console.log(fileNew, fileOld)
  297. for (const k in obj) {
  298. if (!['fileIds', 'fileSet'].includes(k)) {
  299. if (objOld.current[k] !== obj[k]) {
  300. flag = false
  301. }
  302. }
  303. }
  304. if (flag) return MessageFu.warning('未修改藏品信息')
  305. // -----------藏品编辑模块进来---------------
  306. MessageFu.success(`${staTxt.current}成功`)
  307. succFu(
  308. obj,
  309. '编辑',
  310. staTxt.current as '提交',
  311. table || [],
  312. objOld.current.file || [],
  313. objOld.current
  314. )
  315. closeFu()
  316. } else {
  317. // 藏品登记模块
  318. // 删除附件
  319. if (fileDelIdArr.current.length) {
  320. await API_C2dels(fileDelIdArr.current)
  321. }
  322. const res = await API_goodsAdd(obj, idRes ? '编辑' : '新增')
  323. if (res.code === 0) {
  324. MessageFu.success(nowSta.id === 'null' ? `${staTxt.current}成功` : '编辑成功')
  325. succFu(res.data, nowSta.id === 'null' ? '新增' : '编辑', staTxt.current as '提交')
  326. closeFu()
  327. }
  328. }
  329. },
  330. [closeFu, isEdit, nowSta.id, succFu, table]
  331. )
  332. // 点击提交 和存草稿
  333. const staTxt = useRef('')
  334. const btnOk = useCallback((val: '提交' | '存草稿') => {
  335. staTxt.current = val
  336. const btnDom = document.querySelector('#AddGoodsBtn') as HTMLDivElement
  337. if (btnDom) btnDom.click()
  338. }, [])
  339. const [tabTxt, setTabTxt] = useState('基本信息')
  340. // 从入馆入藏藏品中登记
  341. const [selectOne, setSelectOne] = useState(false)
  342. const selectArr = useRef<C1GoodType[]>([])
  343. return (
  344. <div className={styles.AddGoods}>
  345. <div className='AddGtit'>
  346. <div className='AddGtitLL'>
  347. {isEdit ? <span>藏品修改{editSnap ? '-编辑' : '-新增'}</span> : null}
  348. {['基本信息', '附属信息', '附件信息'].map(v => (
  349. <Button
  350. onClick={() => setTabTxt(v)}
  351. key={v}
  352. type={tabTxt === v ? 'primary' : 'default'}
  353. >
  354. {v}
  355. </Button>
  356. ))}
  357. </div>
  358. <div className='AddGtitRR'>
  359. {nowSta.id === 'null' ? (
  360. <>
  361. <Button onClick={() => setSelectOne(true)}>从入馆入藏中登记</Button>&emsp;
  362. <Button onClick={() => history.push('/goodEdit')}>查看历史记录</Button>
  363. </>
  364. ) : null}
  365. </div>
  366. </div>
  367. <div className='B3Nmain'>
  368. <Form
  369. scrollToFirstError={true}
  370. ref={FormBoxRef}
  371. name='basic'
  372. onFinish={onFinish}
  373. onFinishFailed={onFinishFailed}
  374. autoComplete='off'
  375. >
  376. {/* 基本信息 */}
  377. <div hidden={tabTxt !== '基本信息'}>
  378. <div className='B3Ntit'>档案信息</div>
  379. <div className='B3Nbox'>
  380. <div className='B3Nrow B3Nrow0'>
  381. <Form.Item
  382. label='藏品编号'
  383. name='numName'
  384. rules={[{ required: true, message: '请选择编号类型' }]}
  385. >
  386. <Select
  387. style={{ width: 140 }}
  388. options={selectObj['藏品编号类型']}
  389. placeholder='请选择'
  390. />
  391. </Form.Item>
  392. <Form.Item name='num' rules={[{ required: true, message: '请输入藏品编号' }]}>
  393. <Input maxLength={30} showCount placeholder='请输入内容' />
  394. </Form.Item>
  395. </div>
  396. <div className='B3Nrow'>
  397. <Form.Item label='分类号' name='numType'>
  398. <Input maxLength={30} showCount placeholder='请输入内容' />
  399. </Form.Item>
  400. </div>
  401. <div className='B3Nrow'>
  402. <div className='B3Nrowll'>制档人:</div>
  403. <div className='B3Nrowrr'>{txtArr[0]}</div>
  404. </div>
  405. <div className='B3Nrow'>
  406. <div className='B3Nrowll'>制档日期:</div>
  407. <div className='B3Nrowrr'>{txtArr[1]}</div>
  408. </div>
  409. </div>
  410. <div className='B3Ntit'>藏品基本信息</div>
  411. <div className='B3Nbox'>
  412. <div className='B3Nrow'>
  413. <Form.Item
  414. label='藏品名称'
  415. name='name'
  416. rules={[{ required: true, message: '请输入藏品名称' }]}
  417. >
  418. <Input maxLength={30} showCount placeholder='请输入内容' />
  419. </Form.Item>
  420. </div>
  421. <div className='B3Nrow'>
  422. <Form.Item label='藏品原名' name='namePrimitive'>
  423. <Input maxLength={30} showCount placeholder='请输入内容' />
  424. </Form.Item>
  425. </div>
  426. <div className='B3Nrow'>
  427. <Form.Item
  428. label='文物级别'
  429. name='dictLevel'
  430. rules={[{ required: true, message: '请选择文物级别' }]}
  431. >
  432. <Select options={selectObj['文物级别']} placeholder='请选择' />
  433. </Form.Item>
  434. </div>
  435. <div className='B3Nrow'>
  436. <Form.Item
  437. label='文物类别'
  438. name='dictType'
  439. rules={[{ required: true, message: '请选择文物类别' }]}
  440. >
  441. <Cascader
  442. options={cascaderObjFu()['文物类别']}
  443. placeholder='请选择'
  444. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  445. allowClear={false}
  446. />
  447. </Form.Item>
  448. </div>
  449. <div className='B3Nrow'>
  450. <Form.Item label='馆内藏品分类1' name='dictHouse1'>
  451. <Cascader
  452. options={cascaderObjFu()['馆内分类1']}
  453. placeholder='请选择'
  454. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  455. allowClear={true}
  456. changeOnSelect
  457. />
  458. </Form.Item>
  459. </div>
  460. <div className='B3Nrow'>
  461. <Form.Item label='馆内藏品分类2' name='dictHouse2'>
  462. <Cascader
  463. options={cascaderObjFu()['馆内分类2']}
  464. placeholder='请选择'
  465. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  466. allowClear={true}
  467. changeOnSelect
  468. />
  469. </Form.Item>
  470. </div>
  471. <div className='B3Nrow'>
  472. <Form.Item
  473. label='年代'
  474. name='dictAge'
  475. rules={[{ required: true, message: '请选择年代' }]}
  476. >
  477. <Cascader
  478. options={[...cascaderObjFu()['年代'], { name: '其他', id: '其他' }]}
  479. onChange={value => setAgeAc(value[0] === '其他')}
  480. placeholder='请选择'
  481. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  482. allowClear={false}
  483. />
  484. </Form.Item>
  485. </div>
  486. <div className='B3Nrow'>
  487. <Form.Item
  488. label='具体年代'
  489. name='ageInfo'
  490. rules={[{ required: ageAc, message: '请输入内容' }]}
  491. >
  492. <Input maxLength={30} showCount placeholder='请输入内容' />
  493. </Form.Item>
  494. </div>
  495. <div className='B3Nrow'>
  496. <Form.Item label='制作时间' name='dateMaking'>
  497. <DatePicker placeholder='请选择日期' />
  498. </Form.Item>
  499. <div className='B3NrowDing'>
  500. <Form.Item label='作者' name='author'>
  501. <Input maxLength={30} showCount placeholder='请输入内容' />
  502. </Form.Item>
  503. </div>
  504. </div>
  505. <div className='B3Nrow'>
  506. <Form.Item label='作者介绍' name='authorDesc'>
  507. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  508. </Form.Item>
  509. </div>
  510. <div className='B3Nrow B3NrowNumOrCas'>
  511. <Form.Item
  512. label='数量'
  513. name='pcs'
  514. rules={[{ required: true, message: '请输入正整数' }]}
  515. >
  516. <InputNumber min={1} max={99999999} precision={0} placeholder='请输入正整数' />
  517. </Form.Item>
  518. <Form.Item name='pcsUnit' rules={[{ required: true, message: '请选择单位' }]}>
  519. <Cascader
  520. options={cascaderObjFu()['数量单位']}
  521. placeholder='请选择'
  522. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  523. allowClear={false}
  524. />
  525. </Form.Item>
  526. </div>
  527. <div className='B3Nrow'>
  528. <Form.Item label='实际数量' name='pcsActual'>
  529. <Input maxLength={30} showCount placeholder='请输入内容' />
  530. </Form.Item>
  531. </div>
  532. <div className='B3Nrow B3Nrow1'>
  533. <Form.Item
  534. label={
  535. <div>
  536. <span className='B3Nred'> * </span>质地
  537. </div>
  538. }
  539. name='dictTexture1'
  540. >
  541. <Cascader
  542. options={cascaderObjFu()['质地']}
  543. placeholder='请选择'
  544. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  545. />
  546. </Form.Item>
  547. <Form.Item name='dictTexture2'>
  548. <Cascader
  549. options={cascaderObjFu()['复合或组合质地']}
  550. placeholder='请选择'
  551. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  552. />
  553. </Form.Item>
  554. <Form.Item name='dictTexture3' rules={[{ required: true, message: '请选择质地3' }]}>
  555. <Cascader
  556. options={cascaderObjFu()['单一质地']}
  557. placeholder='请选择'
  558. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  559. allowClear={false}
  560. />
  561. </Form.Item>
  562. <div className='B3NrowDing'>
  563. <Form.Item
  564. label='完残程度'
  565. name='dictTorn'
  566. rules={[{ required: true, message: '请选择完残程度' }]}
  567. >
  568. <Cascader
  569. options={cascaderObjFu()['完残程度']}
  570. placeholder='请选择'
  571. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  572. allowClear={false}
  573. />
  574. </Form.Item>
  575. </div>
  576. </div>
  577. {/* 封面 */}
  578. {/* <div className='formRow'>
  579. <div className='formLeft'>封面图:</div>
  580. <div className='formRight'>
  581. <ZupOne
  582. ref={ZupThumbRef}
  583. isLook={false}
  584. fileCheck={false}
  585. size={5}
  586. dirCode='goodsAdd'
  587. myUrl='cms/goods/upload'
  588. format={['image/jpeg', 'image/png']}
  589. formatTxt='png、jpg和jpeg'
  590. checkTxt='请上传封面图!'
  591. upTxt='最多1张'
  592. myType='thumb'
  593. />
  594. </div>
  595. </div> */}
  596. <div className='B3Nrow'>
  597. <Form.Item label='完残情况' name='torn'>
  598. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  599. </Form.Item>
  600. </div>
  601. <div className='B3Nrow'>
  602. <Form.Item label='保存状态' name='preserveState'>
  603. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  604. </Form.Item>
  605. </div>
  606. <div className='B3Nrow'>
  607. <Form.Item label='色泽' name='color'>
  608. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  609. </Form.Item>
  610. </div>
  611. <div className='B3Nrow'>
  612. <Form.Item label='用途' name='uses'>
  613. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  614. </Form.Item>
  615. </div>
  616. <div className='B3Nrow'>
  617. <Form.Item label='形状描述' name='shape'>
  618. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  619. </Form.Item>
  620. </div>
  621. <div className='B3Nrow'>
  622. <Form.Item label='著者' name='pressAuthor'>
  623. <Input maxLength={30} showCount placeholder='请输入内容' />
  624. </Form.Item>
  625. </div>
  626. <div className='B3Nrow'>
  627. <Form.Item label='版本' name='pressVersion'>
  628. <Input maxLength={30} showCount placeholder='请输入内容' />
  629. </Form.Item>
  630. </div>
  631. <div className='B3Nrow'>
  632. <Form.Item label='存卷' name='pressFile'>
  633. <Input maxLength={30} showCount placeholder='请输入内容' />
  634. </Form.Item>
  635. </div>
  636. {/* 备注 */}
  637. <div className='formRow formRow2'>
  638. <div className='formLeft'>备注:</div>
  639. <div className='formRight'>
  640. <ZRichTexts
  641. check={false}
  642. dirCode='goodsAdd'
  643. myUrl='cms/goodsFile/upload'
  644. isLook={false}
  645. ref={ZRichTextRef}
  646. isOne={true}
  647. upAudioBtnNone={true}
  648. />
  649. </div>
  650. </div>
  651. </div>
  652. </div>
  653. {/* 附属信息 */}
  654. <div hidden={tabTxt !== '附属信息'}>
  655. <div className='B3Ntit'>尺寸和质量</div>
  656. <div className='B3Nbox'>
  657. <div className='formRow formRow2'>
  658. <div className='formLeft'>尺寸:</div>
  659. <div className='formRight formRightSize'>
  660. <Form.Item label='通长' name='sizeL'>
  661. <InputNumber
  662. min={0}
  663. max={99999999}
  664. precision={2}
  665. placeholder='请输入数字,最多两位小数'
  666. />
  667. </Form.Item>
  668. <Form.Item label='通宽' name='sizeW'>
  669. <InputNumber
  670. min={0}
  671. max={99999999}
  672. precision={2}
  673. placeholder='请输入数字,最多两位小数'
  674. />
  675. </Form.Item>
  676. <Form.Item label='通高' name='sizeH'>
  677. <InputNumber
  678. min={0}
  679. max={99999999}
  680. precision={2}
  681. placeholder='请输入数字,最多两位小数'
  682. />
  683. </Form.Item>
  684. <Form.Item name='sizeUnit'>
  685. <Cascader
  686. options={cascaderObjFu()['尺寸单位']}
  687. placeholder='请选择'
  688. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  689. />
  690. </Form.Item>
  691. </div>
  692. </div>
  693. <div className='B3Nrow'>
  694. <Form.Item
  695. label='质量范围'
  696. name='qualityDictScope'
  697. rules={[{ required: true, message: '请选择质量范围' }]}
  698. >
  699. <Cascader
  700. options={cascaderObjFu()['质量范围']}
  701. placeholder='请选择'
  702. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  703. allowClear={false}
  704. />
  705. </Form.Item>
  706. <div className='B3NrowDing B3NrowDing2'>
  707. <Form.Item label='具体质量' name='quality'>
  708. <InputNumber
  709. min={0}
  710. max={99999999}
  711. precision={2}
  712. placeholder='请输入数字,最多两位小数'
  713. />
  714. </Form.Item>
  715. <Form.Item name='qualityUnit'>
  716. <Cascader
  717. options={cascaderObjFu()['质量单位']}
  718. placeholder='请选择'
  719. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  720. />
  721. </Form.Item>
  722. </div>
  723. </div>
  724. <div className='B3Nrow'>
  725. <Form.Item label='具体尺寸' name='sizeInfo'>
  726. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  727. </Form.Item>
  728. </div>
  729. </div>
  730. <div className='B3Ntit'>入藏及来源</div>
  731. <div className='B3Nbox'>
  732. <div className='B3Nrow'>
  733. <Form.Item label='入馆凭证号' name='inHouseNum'>
  734. <Input maxLength={30} showCount placeholder='请输入内容' />
  735. </Form.Item>
  736. </div>
  737. <div className='B3Nrow'>
  738. <Form.Item label='入藏凭证号' name='inGoodsNum'>
  739. <Input maxLength={30} showCount placeholder='请输入内容' />
  740. </Form.Item>
  741. </div>
  742. <div className='B3Nrow'>
  743. <Form.Item
  744. label='入藏日期'
  745. name='inGoodsDate'
  746. rules={[
  747. {
  748. pattern: /^(?:\d{4}(?:-(0[1-9]|1[0-2])(?:-(0[1-9]|[12]\d|3[01]))?)?)?$/,
  749. message: '格式应为YYYY、YYYY-MM或YYYY-MM-DD(如2000、2000-01、2000-01-01)'
  750. }
  751. ]}
  752. getValueFromEvent={e => e.target.value.replace(/\s+/g, '')}
  753. >
  754. <Input
  755. maxLength={10}
  756. showCount
  757. placeholder='请输入日期'
  758. onKeyPress={e => /[^0-9-]/.test(e.key) && e.preventDefault()}
  759. />
  760. </Form.Item>
  761. </div>
  762. <div className='B3Nrow'>
  763. <Form.Item
  764. label='入藏日期范围'
  765. className='B3NlongTxt'
  766. name='inDictDateScope'
  767. // rules={[{ required: true, message: '请选择入藏日期范围' }]}
  768. >
  769. <Cascader
  770. options={cascaderObjFu()['入藏日期范围']}
  771. placeholder='请选择'
  772. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  773. allowClear={true}
  774. />
  775. </Form.Item>
  776. </div>
  777. <div className='B3Nrow'>
  778. <Form.Item label='入藏去向' name='accountType'>
  779. <Select options={selectObj['入藏去向']} placeholder='请选择' />
  780. </Form.Item>
  781. </div>
  782. <div className='B3Nrow'>
  783. <Form.Item
  784. label='来源'
  785. name='source'
  786. rules={[{ required: true, message: '请选择来源' }]}
  787. >
  788. <Cascader
  789. options={cascaderObjFu()['来源']}
  790. placeholder='请选择'
  791. fieldNames={{ label: 'name', value: 'id', children: 'children' }}
  792. allowClear={false}
  793. />
  794. </Form.Item>
  795. </div>
  796. <div className='B3Nrow'>
  797. <Form.Item label='来源详情' name='sourceInfo'>
  798. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  799. </Form.Item>
  800. </div>
  801. <div className='B3Nrow'>
  802. <Form.Item label='征集经过' name='sourcePass'>
  803. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  804. </Form.Item>
  805. </div>
  806. <div className='B3Nrow'>
  807. <Form.Item label='铭记题跋' name='sourcePreface'>
  808. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  809. </Form.Item>
  810. </div>
  811. <div className='B3Nrow'>
  812. <Form.Item label='鉴藏印记' name='sourceStamp'>
  813. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  814. </Form.Item>
  815. </div>
  816. </div>
  817. <div className='B3Ntit'>藏品历史及流传</div>
  818. <div className='B3Nbox'>
  819. <div className='B3Nrow'>
  820. <Form.Item label='著作及有关书目' className='B3NlongTxt2' name='historyWork'>
  821. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  822. </Form.Item>
  823. </div>
  824. <div className='B3Nrow'>
  825. <Form.Item label='流传经历' name='historyUndergo'>
  826. <TextArea maxLength={500} showCount placeholder='请输入内容' />
  827. </Form.Item>
  828. </div>
  829. </div>
  830. </div>
  831. {/* 附件信息 */}
  832. <div className='B3Nbox B3Nbox1' hidden={tabTxt !== '附件信息'}>
  833. <div className='B3Ntit'>
  834. <div className='B3Ntitll'>
  835. <span>附件类型为图像并且格式为图片的第一份数据为封面图</span>
  836. </div>
  837. <Z3upFiles
  838. max={1000}
  839. isLook={false}
  840. ref={filesRef}
  841. fileCheck={false}
  842. dirCode='goodsAdd'
  843. myUrl='cms/goods/upload'
  844. lookData={[]}
  845. size={500}
  846. noShowList={true}
  847. fileRes={obj => setTable([...table, obj])}
  848. />
  849. </div>
  850. {/* 表格 */}
  851. <MyTable
  852. list={table}
  853. columnsTemp={Y33tableC}
  854. lastBtn={tableLastBtn}
  855. startBtn={startBtn}
  856. pagingInfo={false}
  857. />
  858. </div>
  859. {/* 确定和取消按钮 */}
  860. <Form.Item className='B3Nbtn'>
  861. <Button type='primary' htmlType='submit' id='AddGoodsBtn' hidden>
  862. 提交
  863. </Button>
  864. <Button type='primary' onClick={() => btnOk('提交')}>
  865. 提交
  866. </Button>
  867. {(nowSta.id === 'null' || isEdit) && !editSnap ? (
  868. <>
  869. &emsp;
  870. <Button type='primary' onClick={() => btnOk('存草稿')}>
  871. 存草稿
  872. </Button>
  873. </>
  874. ) : null}
  875. {nowSta.key === '藏品登记' ? null : (
  876. <>
  877. &emsp;
  878. <MyPopconfirm txtK='取消' onConfirm={closeFu} />
  879. </>
  880. )}
  881. </Form.Item>
  882. </Form>
  883. </div>
  884. {/* 从入馆入藏藏品中选择一个 */}
  885. {selectOne ? (
  886. <ZGaddNow
  887. register={true}
  888. nowSta={{ key: '藏品登记', id: 'cms/register/goods/getList' }}
  889. closeFu={() => setSelectOne(false)}
  890. dataResFu={data => {
  891. if (data.length && data[0].id) {
  892. selectArr.current = data
  893. getInfo(data[0].id)
  894. } else {
  895. selectArr.current = []
  896. FormBoxRef.current?.setFieldsValue({})
  897. }
  898. }}
  899. oldCheckArr={selectArr.current}
  900. isOne={true}
  901. />
  902. ) : null}
  903. </div>
  904. )
  905. }
  906. const MemoAddGoods = React.memo(AddGoods)
  907. export default MemoAddGoods