index.tsx 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. import React, { useEffect, useState } from 'react'
  2. import Container, { ContainerBody } from 'components/Container'
  3. import Helmet from 'react-helmet'
  4. import Box from 'components/Box'
  5. import styles from 'containers/DataManagerView/index.less'
  6. import {
  7. Button,
  8. Divider,
  9. Dropdown,
  10. Icon,
  11. Menu,
  12. message,
  13. Popconfirm,
  14. Spin,
  15. Table
  16. } from 'antd'
  17. import classnames from 'classnames'
  18. import request from 'utils/request'
  19. import api from 'utils/api'
  20. import { ColumnProps } from 'antd/lib/table'
  21. import {
  22. IClassification,
  23. IQualityTask
  24. } from 'containers/DataGovernanceQualityAudit/types'
  25. import ClassificationsFormModal from 'containers/DataGovernanceQualityAudit/components/ClassificationsFormModal'
  26. import QualityTaskFormModal from 'containers/DataGovernanceQualityAudit/components/QualityTaskFormModal'
  27. import ScheduleFormModal from 'containers/DataGovernanceQualityAudit/components/ScheduleFormModal'
  28. import header from 'containers/Display/Editor/Header'
  29. export default function DataGovernanceQualityAudit() {
  30. const [tableLoading, setTableLoading] = useState(false)
  31. const [treeLoading, setTreeLoading] = useState(false)
  32. const [selectedKey, setSelectedKey] = useState<number>()
  33. const [qualityTasks, setQualityTasks] = useState<IQualityTask[]>([])
  34. const [qtVisible, setQtVisible] = useState(false)
  35. const [qtLoading, setQtLoading] = useState(false)
  36. // eslint-disable-next-line no-undef
  37. const [qtForm, setQtForm] = useState<Partial<IQualityTask>>({})
  38. const [classifications, setClassifications] = useState<IClassification[]>([])
  39. const [cfVisible, setCfVisible] = useState(false)
  40. const [cfLoading, setCfLoading] = useState(false)
  41. const [cfForm, setCfForm] = useState<IClassification>({})
  42. const [scVisible, setScVisible] = useState(false)
  43. const [scLoading, setSCLoading] = useState(false)
  44. const [scForm, setSCForm] = useState<IClassification>({})
  45. const tableColumns: Array<ColumnProps<IQualityTask>> = [
  46. {
  47. title: '任务名称',
  48. dataIndex: 'taskName'
  49. },
  50. {
  51. title: '元数据名称',
  52. dataIndex: 'metadataName'
  53. },
  54. {
  55. title: '稽核字段个数',
  56. dataIndex: 'standardName'
  57. },
  58. {
  59. title: '操作',
  60. render: (_, data) => (
  61. <>
  62. <a
  63. onClick={() => {
  64. setQtVisible(true)
  65. setQtForm(data)
  66. }}
  67. >
  68. 编辑
  69. </a>
  70. <Divider type="vertical" />
  71. <Dropdown
  72. overlay={
  73. <Menu>
  74. <Menu.Item key="0" onClick={() => setScVisible(true)}>
  75. 设置调度
  76. </Menu.Item>
  77. <Menu.Item key="1">
  78. <Popconfirm
  79. title="确定立即稽查吗?"
  80. placement="bottom"
  81. onConfirm={() => handleSetDispatchRightNow(data)}
  82. >
  83. <a>立即稽查</a>
  84. </Popconfirm>
  85. </Menu.Item>
  86. <Menu.Item key="2">修改</Menu.Item>
  87. <Menu.Item key="3">
  88. <Popconfirm
  89. title="确定删除?"
  90. placement="bottom"
  91. // onConfirm
  92. >
  93. <a>删除</a>
  94. </Popconfirm>
  95. </Menu.Item>
  96. </Menu>
  97. }
  98. >
  99. <a>
  100. {' '}
  101. 更多 <Icon type="down" />
  102. </a>
  103. </Dropdown>
  104. </>
  105. )
  106. }
  107. ]
  108. const handleEditTreeItem = (form: IClassification) => {
  109. setCfForm(form)
  110. setCfVisible(true)
  111. }
  112. const handleDeleteTreeItem = async (c: IClassification) => {
  113. try {
  114. setTreeLoading(true)
  115. const data = await request(`${api.deleteAuditClassification}${c.id}`, {
  116. method: 'DELETE'
  117. })
  118. // @ts-ignore
  119. if (data?.header?.code === 200) {
  120. message.success({ content: '删除成功' })
  121. await queryClassifications()
  122. } else {
  123. // @ts-ignore
  124. // tslint:disable-next-line:no-unused-expression
  125. data?.header?.msg && message.error({ content: data?.header?.msg })
  126. }
  127. } finally {
  128. setTreeLoading(false)
  129. }
  130. }
  131. const renderTree = (catalogues: IClassification[]) => (
  132. <>
  133. {catalogues.map((c, idx) => (
  134. <div
  135. key={c.id ?? idx}
  136. className={classnames(styles.treeNode, {
  137. [styles.treeNodeSelected]: selectedKey === c.id
  138. })}
  139. >
  140. <span
  141. className={styles.treeNodeLeft}
  142. onClick={() => {
  143. setSelectedKey(c.id)
  144. }}
  145. >
  146. <Icon type="file" />
  147. {c.name}
  148. </span>
  149. <Dropdown
  150. overlay={() => (
  151. <Menu>
  152. <Menu.Item key="0" onClick={() => handleEditTreeItem(c)}>
  153. 编辑
  154. </Menu.Item>
  155. <Menu.Item key="1">
  156. <Popconfirm
  157. title="确定删除?"
  158. placement="bottom"
  159. onConfirm={() => handleDeleteTreeItem(c)}
  160. >
  161. <a>删除</a>
  162. </Popconfirm>
  163. </Menu.Item>
  164. </Menu>
  165. )}
  166. trigger={['click']}
  167. >
  168. <Icon type="more" />
  169. </Dropdown>
  170. </div>
  171. ))}
  172. </>
  173. )
  174. const handleSetDispatchRightNow = async (data: IQualityTask) => {
  175. try {
  176. setTableLoading(true)
  177. const result = await request(
  178. `${api.setDispatchRightNow}${data.cronJobId}`,
  179. {
  180. method: 'PUT'
  181. }
  182. )
  183. // @ts-ignore
  184. if (result.header.code === 200) {
  185. message.success({ content: '立即稽核完成' })
  186. } else {
  187. // @ts-ignore
  188. // tslint:disable-next-line:no-unused-expression
  189. result?.header?.msg && message.success({ content: result.header.msg })
  190. }
  191. } finally {
  192. setTableLoading(false)
  193. }
  194. }
  195. const queryClassifications = async () => {
  196. try {
  197. setTreeLoading(true)
  198. const data = await request(api.getAuditClassification, { method: 'GET' })
  199. // @ts-ignore
  200. setClassifications(data?.payload ?? [])
  201. // @ts-ignore
  202. setSelectedKey(data?.payload?.[0]?.id)
  203. } finally {
  204. setTreeLoading(false)
  205. }
  206. }
  207. const queryQualityTasks = async () => {
  208. try {
  209. setTableLoading(true)
  210. const data = await request(`${api.getQualityTask}?pId=${selectedKey}`, {
  211. method: 'GET'
  212. })
  213. // @ts-ignore
  214. setQualityTasks(data?.payload ?? [])
  215. } finally {
  216. setTableLoading(false)
  217. }
  218. }
  219. const handleSaveCfForm = async (form: IClassification) => {
  220. try {
  221. setCfLoading(true)
  222. const url = cfForm.id
  223. ? api.updateAuditClassification + cfForm.id
  224. : api.createAuditClassification
  225. const result = await request(url, {
  226. method: cfForm.id ? 'PUT' : 'POST',
  227. data: { ...cfForm, ...form }
  228. })
  229. // @ts-ignore
  230. if (result?.header?.code === 200) {
  231. setCfVisible(false)
  232. await queryClassifications()
  233. }
  234. } finally {
  235. setCfLoading(false)
  236. }
  237. }
  238. useEffect(() => {
  239. queryClassifications()
  240. }, [])
  241. useEffect(() => {
  242. if (selectedKey) {
  243. queryQualityTasks()
  244. }
  245. }, [selectedKey])
  246. return (
  247. <Container>
  248. <Helmet title="质量稽核" />
  249. <ContainerBody>
  250. <Box>
  251. <Box.Header>
  252. <Box.Title>质量稽核</Box.Title>
  253. </Box.Header>
  254. <Box.Body>
  255. <div className={styles.treeTableContainer}>
  256. <div className={styles.treeContainer}>
  257. <div className={styles.treeTitle}>
  258. <h6>数据质量</h6>
  259. <div
  260. className={styles.treePlusNode}
  261. onClick={() => {
  262. setCfForm({})
  263. setCfVisible(true)
  264. }}
  265. >
  266. <Icon type="plus" />
  267. </div>
  268. </div>
  269. <div className={styles.treeContent}>
  270. <Spin spinning={treeLoading}>
  271. {renderTree(classifications)}
  272. </Spin>
  273. </div>
  274. </div>
  275. <div style={{ flex: 1 }}>
  276. <div style={{ padding: '0 0 20px' }}>
  277. <Button
  278. type="primary"
  279. icon="plus"
  280. onClick={() => {
  281. setQtVisible(true)
  282. setQtForm(null)
  283. }}
  284. >
  285. 新增
  286. </Button>
  287. </div>
  288. <Table
  289. style={{ flex: 1 }}
  290. bordered
  291. rowKey="id"
  292. loading={tableLoading}
  293. dataSource={qualityTasks}
  294. columns={tableColumns}
  295. pagination={false}
  296. // onChange={this.tableChange}
  297. />
  298. </div>
  299. </div>
  300. <br />
  301. </Box.Body>
  302. </Box>
  303. </ContainerBody>
  304. <ClassificationsFormModal
  305. visible={cfVisible}
  306. formView={cfForm}
  307. onSave={handleSaveCfForm}
  308. loading={cfLoading}
  309. onCancel={() => setCfVisible(false)}
  310. />
  311. <QualityTaskFormModal
  312. visible={qtVisible}
  313. formView={qtForm}
  314. onSave={handleSaveCfForm}
  315. loading={qtLoading}
  316. onCancel={() => setQtVisible(false)}
  317. />
  318. <ScheduleFormModal
  319. visible={scVisible}
  320. loading={scLoading}
  321. formView={scForm}
  322. onSave={undefined}
  323. onCancel={() => setScVisible(false)}
  324. />
  325. </Container>
  326. )
  327. }