index.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { ZhSubmitButton, ZhUploadButton } from '@/components/Button'
  2. import DatePicker from '@/components/DatePicker'
  3. import { apiGetFileList } from '@/components/FileModal/api'
  4. import Header from '@/components/Header'
  5. import Slot from '@/components/Header/slot'
  6. import OssUploadModal from '@/components/OssUpload'
  7. import SvgIcon from '@/components/SvgIcon'
  8. import { userStore } from '@/store/mobx'
  9. import { iFile } from '@/types/file'
  10. import { apiDelFile } from '@/utils/common/api'
  11. import consts from '@/utils/consts'
  12. import { dayjsFormat } from '@/utils/util'
  13. import { Button, Input, Pagination, Tooltip } from 'antd'
  14. import locale from 'antd/es/date-picker/locale/zh_CN'
  15. import dayjs from 'dayjs'
  16. import React, { useEffect, useState } from 'react'
  17. import { RouteComponentProps } from 'react-router'
  18. import { apiGetSafeDetail, apiSaveFileInfo } from './api'
  19. import styles from './index.module.scss'
  20. const { TextArea } = Input
  21. interface iDetailState {
  22. auditName: string
  23. auditors: any[]
  24. bidsectionId: string
  25. code: string
  26. createTime: string | undefined
  27. demand: string
  28. file: iFileState
  29. id: string
  30. inspection: string
  31. inspectionDetail: string
  32. position: string
  33. status: number
  34. }
  35. interface iFileState {
  36. fileList: any[]
  37. total: number
  38. }
  39. const Detail:React.FC<RouteComponentProps> = (props) => {
  40. const [ visible, setVisible ] = useState<boolean>(false)
  41. const [ detail, setDetail ] = useState<iDetailState>({
  42. auditName: "",
  43. auditors: [],
  44. bidsectionId: "",
  45. code: "",
  46. createTime: "",
  47. demand: "",
  48. file: { fileList: [], total: 0 },
  49. id: "",
  50. inspection: "",
  51. inspectionDetail: "",
  52. position: "",
  53. status: 0
  54. })
  55. useEffect(() => {
  56. initData()
  57. }, [])
  58. const initData = async() => {
  59. const { saveId = "" } = props.location.state as any
  60. const { code = -1, data = {} } = await apiGetSafeDetail(saveId)
  61. if (code === consts.RET_CODE.SUCCESS) {
  62. setDetail({ ...detail, ...data })
  63. }
  64. }
  65. const onCreate = async (fileList: iFile[]) => {
  66. const { code = -1 } = await apiSaveFileInfo(fileList, consts.DATA_TYPE.SAFE, detail.id)
  67. if (code === consts.RET_CODE.SUCCESS) {
  68. const newFiles = detail.file.fileList.concat(fileList.map(file => {
  69. return { ...file, accountName: userStore.userInfo.name }
  70. }))
  71. setDetail({ ...detail, file: { ...detail.file, fileList: newFiles } })
  72. setVisible(false)
  73. }
  74. }
  75. const onShow = (show: boolean) => setVisible(show)
  76. const fileListChange = async (pageNo: number = 1, pageSize: number = 10) => {
  77. const { code = -1, data } = await apiGetFileList(consts.DATA_TYPE.SAFE,detail.id, pageNo, pageSize)
  78. if (code === consts.RET_CODE.SUCCESS) {
  79. setDetail({ ...detail, file: { ...detail.file, fileList: data } })
  80. }
  81. }
  82. const delFile = async(id: string) => {
  83. const { code = -1 } = await apiDelFile(id)
  84. if (code === consts.RET_CODE.SUCCESS) {
  85. const newFiles = detail.file.fileList.map(file => file.id !== id)
  86. setDetail({ ...detail, file: { ...detail.file, fileList: newFiles } })
  87. }
  88. }
  89. return (
  90. <div className="wrap-contaniner">
  91. <Header title="安全巡检">
  92. <Slot position="right">
  93. <div>
  94. <ZhSubmitButton size="small">提交审批</ZhSubmitButton>
  95. </div>
  96. </Slot>
  97. </Header>
  98. <div className={styles.detailContainer}>
  99. <div className={styles.content}>
  100. <h4 className={styles.header}>{detail.code}</h4>
  101. <table className="pi-table pi-bordered">
  102. <thead>
  103. <tr>
  104. <th colSpan={2} className="pi-text-center">安全巡检单</th>
  105. </tr>
  106. </thead>
  107. <tbody>
  108. <tr><th style={{ width: "150px" }}>检查项目</th><td><TextArea value={detail.inspection}></TextArea></td></tr>
  109. <tr><th style={{ width: "150px" }}>现场检查情况</th><td><TextArea value={detail.inspectionDetail}></TextArea></td></tr>
  110. <tr><th style={{ width: "150px" }}>处理要求及措施</th><td><TextArea value={detail.demand}></TextArea></td></tr>
  111. <tr>
  112. <th style={{ width: "150px" }}>检查日期</th>
  113. <td><DatePicker size="small" locale={locale} allowClear={false} value={dayjs(detail.createTime)} onChange={(value) => setDetail({ ...detail, createTime: value?.format() })}></DatePicker></td>
  114. </tr>
  115. <tr><th style={{ width: "150px" }}>质检员</th><td>{detail.auditName}</td></tr>
  116. </tbody>
  117. </table>
  118. <table className="pi-table pi-bordered mt-3">
  119. <thead>
  120. <tr>
  121. <th></th>
  122. <th className="pi-text-center">附件</th>
  123. <th className="pi-text-center">上传者</th>
  124. <th className="pi-text-center" style={{ width: 200 }}>上传时间</th>
  125. <th className="pi-text-center">操作</th>
  126. </tr>
  127. </thead>
  128. <tbody>
  129. <tr><td colSpan={5}><ZhUploadButton size="small" icon={<SvgIcon type="xxh-cloud-upload"/>} onClick={() => setVisible(true)}>上传附件</ZhUploadButton></td></tr>
  130. {
  131. detail.file.fileList?.map((file, idx) => {
  132. return (
  133. <tr key={idx}>
  134. <td className="pi-width-70">{idx+1}</td>
  135. <td style={{ width: 383, maxWidth: 383, overflow: 'hidden', whiteSpace: 'nowrap',textOverflow:'ellipsis' }}>
  136. <a href={consts.OSS_PATH.REVIEW + file.filepath} target="_blank" rel="noopener noreferrer">{file.filename}</a>
  137. </td>
  138. <td className="pi-text-center">{file.accountName}</td><td className="pi-text-center">{dayjsFormat(file.createTime)}</td>
  139. <td className="pi-text-center pi-width-90">
  140. <Tooltip title="移除">
  141. <Button size="small" type="text" icon={<SvgIcon type="xxh-times-circle1"/>} style={{ color: "#df3f45" }} onClick={() => delFile(file.id)}></Button>
  142. </Tooltip>
  143. </td>
  144. </tr>
  145. )
  146. })
  147. }
  148. <tr><td colSpan={5} className="pi-text-right">
  149. {
  150. detail.file.total ?
  151. <Pagination
  152. defaultCurrent={1}
  153. size="small"
  154. pageSize={consts.PAGE_SIZE}
  155. hideOnSinglePage={true}
  156. total={detail.file.total}
  157. onChange={(page, pageSize) => fileListChange(page, pageSize)}
  158. >
  159. </Pagination>
  160. : ''
  161. }
  162. </td></tr>
  163. </tbody>
  164. </table>
  165. </div>
  166. </div>
  167. <OssUploadModal
  168. visible={visible}
  169. onCancel={() => setVisible(false)}
  170. onCreate={onCreate}
  171. onShow={onShow}
  172. >
  173. </OssUploadModal>
  174. </div>
  175. )
  176. }
  177. export default Detail