index.tsx 10 KB

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