index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. import { GroupItem } from '@/components/AuditContent'
  2. import Authorization from '@/components/Authorization'
  3. import { ZhAuditBackButton, ZhButton, ZhCloseButton, ZhSubmitButton } from '@/components/Button'
  4. import { userStore } from '@/store/mobx'
  5. import { iAuditor, iLatestAuditorState } from '@/types/safe'
  6. import { iAccountGroupItem, iUserInfo } from '@/types/setting'
  7. import { getUserGroup } from '@/utils/common/user'
  8. import { Button, Form, Input, message, Modal, Popover } from 'antd'
  9. import React, { ChangeEvent, useEffect, useMemo, useState } from 'react'
  10. interface iAuditModalProps {
  11. type: 'safe' | 'quality'
  12. onCancel: () => void
  13. modalObj: {
  14. visible: boolean
  15. type: string
  16. loading: boolean
  17. }
  18. auditors: iAuditor[]
  19. onCreate: (values?: any) => void
  20. curAuditor: iLatestAuditorState
  21. }
  22. interface iModalObjState {
  23. searchValue: string
  24. visible: boolean
  25. auditType: string
  26. }
  27. const textObj = {
  28. start: {
  29. title: '提交审批',
  30. okText: '确认提交'
  31. },
  32. delete: {
  33. title: '删除巡检',
  34. okText: '确认删除'
  35. },
  36. close: {
  37. title: '审批关闭',
  38. okText: '确认关闭'
  39. },
  40. back: {
  41. title: '审批退回',
  42. okText: '确认退回'
  43. },
  44. pass: {
  45. title: '审批通过',
  46. okText: '确认通过'
  47. }
  48. }
  49. const AuditModal: React.FC<iAuditModalProps> = props => {
  50. const [ form ] = Form.useForm()
  51. const { modalObj: { visible, type, loading }, onCancel, onCreate, auditors, curAuditor, type: auditType } = props
  52. const [ modal, setModal ] = useState<iModalObjState>({
  53. searchValue: '',
  54. visible: false,
  55. auditType: ''
  56. })
  57. // 是否是审批组的最后一个审核人
  58. const isLastAuditor = useMemo(() => {
  59. const len = auditors.filter(item => item.progress === '0').length
  60. if (len && auditors.filter(item => item.progress === '0')[len - 1].audit_id === userStore.userInfo.id) {
  61. return true
  62. }
  63. return false
  64. }, [ auditors ])
  65. const [ groups, setGroups ] = useState<Array<iAccountGroupItem>>([])
  66. const [ user, setUser ] = useState<iUserInfo>({
  67. account: '',
  68. accountGroup: 0,
  69. company: '',
  70. csrf: '',
  71. enable: 0,
  72. id: '',
  73. isAdmin: 0,
  74. mobile: '',
  75. name: '',
  76. password: '',
  77. position: '',
  78. projectId: '',
  79. role: '',
  80. telephone: ''
  81. })
  82. const comfirmBtnClick = () => {
  83. form.validateFields().then(values => {
  84. form.resetFields()
  85. if (user.id) {
  86. values.audit_id = user.id
  87. }
  88. if (type === 'pass' && isLastAuditor && curAuditor.progress === '0' && !user.id) {
  89. return message.error('请指定整改人!')
  90. }
  91. onCreate(values)
  92. })
  93. }
  94. useEffect(() => {
  95. if (visible && isLastAuditor && type === 'pass') {
  96. initGroupList()
  97. }
  98. if (visible && type === 'back') {
  99. if (curAuditor.progress === '1') {
  100. const len = auditors.filter(item => item.progress === '0').length
  101. const lastChecker = auditors.filter(item => item.progress === '0')[len - 1]
  102. setUser({ ...user, id: lastChecker.id, name: lastChecker.name })
  103. } else {
  104. const newGroup = initAuditBackGroup()
  105. setGroups(newGroup)
  106. }
  107. }
  108. }, [ visible ])
  109. const initGroupList = async (serach?: string) => {
  110. const data = await getUserGroup({ name: serach })
  111. setGroups(data)
  112. }
  113. // 初始化审批退回下拉选择框
  114. const initAuditBackGroup = () => {
  115. const newGroup: iAccountGroupItem[] = []
  116. for (let index = 0; index < 3; index++) {
  117. if (index === 0) {
  118. const newAuditors = auditors
  119. .filter(item => item.progress === '')
  120. .map(item => {
  121. return mapUser(item.name, '', item.position, item.company, item.mobile)
  122. })
  123. newGroup.push({ value: '检查人', children: newAuditors })
  124. }
  125. if (index === 1) {
  126. const newAuditors = auditors
  127. .filter(item => item.progress === '0')
  128. .map(item => {
  129. return mapUser(item.name, item.id, item.position, item.company, item.mobile)
  130. })
  131. newGroup.push({ value: '审批', children: newAuditors })
  132. }
  133. if (index === 2) {
  134. const newAuditors = auditors
  135. .filter(item => item.progress === '1')
  136. .map(item => {
  137. return mapUser(item.name, item.id, item.position, item.company, item.mobile)
  138. })
  139. newGroup.push({ value: '整改', children: newAuditors })
  140. }
  141. }
  142. function mapUser(name: string, id: string, position: string, company: string, mobile: string) {
  143. return {
  144. account: '',
  145. accountGroup: 0,
  146. company,
  147. csrf: '',
  148. enable: 0,
  149. id,
  150. isAdmin: 0,
  151. mobile,
  152. name,
  153. password: '',
  154. position,
  155. projectId: '',
  156. role: '',
  157. telephone: ''
  158. }
  159. }
  160. return newGroup
  161. }
  162. const renderOkBtn = (type: string) => {
  163. if (type === 'start' || type === 'pass') {
  164. return (
  165. <ZhSubmitButton size="small" onClick={comfirmBtnClick} loading={loading}>
  166. {textObj[type]?.okText}
  167. </ZhSubmitButton>
  168. )
  169. } else if (type === 'delete') {
  170. return (
  171. <Authorization type={auditType} auth="delete">
  172. <Button danger size="small" onClick={comfirmBtnClick} loading={loading}>
  173. {textObj[type]?.okText}
  174. </Button>
  175. </Authorization>
  176. )
  177. } else if (type === 'close') {
  178. return (
  179. <Button danger size="small" onClick={comfirmBtnClick} loading={loading}>
  180. {textObj[type]?.okText}
  181. </Button>
  182. )
  183. } else if (type === 'back') {
  184. return (
  185. <ZhAuditBackButton size="small" onClick={comfirmBtnClick} loading={loading}>
  186. {textObj[type]?.okText}
  187. </ZhAuditBackButton>
  188. )
  189. }
  190. }
  191. const search = (value: string) => {
  192. if (value != modal.searchValue) {
  193. setModal({ ...modal, searchValue: value })
  194. initGroupList(value)
  195. }
  196. }
  197. const change = (e: ChangeEvent) => {
  198. e.persist()
  199. const target = e.target as HTMLTextAreaElement
  200. if (!target.value) {
  201. initGroupList()
  202. }
  203. }
  204. const itemSelectHandler = (item: iUserInfo, type: string = '') => {
  205. setUser({ ...user, ...item })
  206. setModal({ ...modal, visible: false, auditType: type })
  207. }
  208. const handleVisibleChange = (visible: boolean) => {
  209. setModal({ ...modal, visible })
  210. }
  211. const showPopover = () => {
  212. setModal({ ...modal, visible: true })
  213. }
  214. return (
  215. <Modal
  216. visible={visible}
  217. title={textObj[type]?.title}
  218. onCancel={onCancel}
  219. getContainer={false}
  220. footer={
  221. <div className="pi-justify-end">
  222. <ZhCloseButton size="small" onClick={onCancel} className="pi-mg-right-5">
  223. 关闭
  224. </ZhCloseButton>
  225. {renderOkBtn(type)}
  226. </div>
  227. }>
  228. <Form form={form} layout="vertical">
  229. {type === 'back' ? (
  230. <>
  231. <Form.Item name="opinion" label="审批意见">
  232. <Input.TextArea rows={5} />
  233. </Form.Item>
  234. {curAuditor.progress !== '1' ? (
  235. <Popover
  236. content={groups.map(item => (
  237. <GroupItem {...item} key={item.value} onSelect={(item: iUserInfo, type?: string) => itemSelectHandler(item, type)} />
  238. ))}
  239. overlayClassName="popover-card"
  240. trigger="click"
  241. visible={modal.visible}
  242. onVisibleChange={visible => handleVisibleChange(visible)}
  243. placement="bottomLeft">
  244. <ZhButton size="small" onClick={showPopover}>
  245. 选择退回流程
  246. </ZhButton>
  247. </Popover>
  248. ) : null}
  249. {user.name ? (
  250. <div className="pi-bordered pi-warning">
  251. <span>已选择退回流程: </span>
  252. <span>{user.name}</span>
  253. </div>
  254. ) : null}
  255. </>
  256. ) : null}
  257. {type === 'delete' ? (
  258. <>
  259. <p className="mb-2">删除后,数据无法恢复,请谨慎操作。</p>
  260. <p className="mb-2">
  261. 请在下方文本框输入文本「<span className="pi-red">确认删除本次巡检</span>」,以此确认删除操作。
  262. </p>
  263. <Form.Item
  264. name="warningText"
  265. rules={[
  266. () => ({
  267. validator(rule, value) {
  268. if (!value || value !== '确认删除本次巡检') {
  269. return Promise.reject('请按照提示信息进行删除操作!')
  270. }
  271. return Promise.resolve()
  272. }
  273. })
  274. ]}>
  275. <Input placeholder="输入文本, 确认删除" />
  276. </Form.Item>
  277. </>
  278. ) : null}
  279. {type === 'start' ? <p>请确认审批流程及信息无误。</p> : null}
  280. {type === 'close' ? (
  281. <>
  282. <Form.Item name="opinion" label="审批意见">
  283. <Input.TextArea rows={5} />
  284. </Form.Item>
  285. <p className="pi-warning">审批关闭,将直接停止该巡检流程。</p>
  286. </>
  287. ) : null}
  288. {type === 'pass' ? (
  289. <>
  290. <Form.Item name="opinion" label="审批意见">
  291. <Input.TextArea rows={5} />
  292. </Form.Item>
  293. {isLastAuditor && curAuditor.progress === '0' ? (
  294. <Popover
  295. title={<Input.Search size="small" placeholder="姓名/手机 检索" onSearch={search} onChange={e => change(e)} />}
  296. content={groups.map(item => (
  297. <GroupItem {...item} key={item.value} onSelect={(item: iUserInfo, type?: string) => itemSelectHandler(item, type)} />
  298. ))}
  299. overlayClassName="popover-card"
  300. trigger="click"
  301. visible={modal.visible}
  302. onVisibleChange={visible => handleVisibleChange(visible)}
  303. placement="bottomLeft">
  304. <ZhButton size="small" onClick={showPopover}>
  305. 指派整改人
  306. </ZhButton>
  307. </Popover>
  308. ) : null}
  309. {user.id ? (
  310. <p className="pi-bordered pi-pd-8 pi-mg-top-5">
  311. <span>已指派整改人: </span>
  312. <span>
  313. {user.name}-{user.position}-{user.company}
  314. </span>
  315. </p>
  316. ) : null}
  317. </>
  318. ) : null}
  319. </Form>
  320. </Modal>
  321. )
  322. }
  323. export default AuditModal