index.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. import React, { Component } from 'react'
  2. import { Modal, Button, Input, message, Upload } from 'antd'
  3. import { FormItem } from 'wptpc-design'
  4. import { yc } from '@/conf/config'
  5. const { TextArea } = Input
  6. class Index extends Component {
  7. state = {
  8. data: null,
  9. style: null,
  10. params: null
  11. };
  12. constructor (props) {
  13. super(props)
  14. let params = null
  15. if (props.params) {
  16. params = props.params
  17. params.header = props.params.header || []
  18. }
  19. this.state = {
  20. params: {
  21. detail: [],
  22. header: [],
  23. needNew: 0,
  24. name: '',
  25. getTokenUrl: '',
  26. ...params
  27. }
  28. }
  29. if (typeof props.getValue === 'function') {
  30. props.getValue(this.onOk)
  31. }
  32. }
  33. // 设置 header 属性字段
  34. setHeader (index, value, key) {
  35. const { params } = this.state
  36. if (params.header[index]) {
  37. params.header[index][key] = value
  38. }
  39. this.setState({
  40. params: params
  41. })
  42. }
  43. // 新增属性字段
  44. addHeader = () => {
  45. const { params } = this.state
  46. this.setState({
  47. params: {
  48. ...params,
  49. header: [
  50. ...params.header,
  51. {
  52. key: '',
  53. value: ''
  54. }
  55. ]
  56. }
  57. })
  58. };
  59. // 删除属性字段
  60. delHeader= (index) =>
  61. this.setState((prevState) => ({
  62. params: {
  63. ...prevState.params,
  64. header: prevState.params.header.filter((_, i) => i !== index)
  65. }
  66. }));
  67. // 设置属性字段
  68. setDetail (i, v, k) {
  69. const { params } = this.state
  70. if (params.detail[i]) {
  71. params.detail[i][k] = v
  72. }
  73. this.setState({
  74. params: params
  75. })
  76. }
  77. // 新增属性字段
  78. addDetail = () => {
  79. const { params } = this.state
  80. this.setState({
  81. params: {
  82. ...params,
  83. detail: [
  84. ...params.detail,
  85. {
  86. url: ''
  87. }
  88. ]
  89. }
  90. })
  91. };
  92. // 删除属性字段
  93. delDetail = (index) =>
  94. this.setState((prevState) => ({
  95. params: {
  96. ...prevState.params,
  97. detail: prevState.params.detail.filter((_, i) => i !== index)
  98. }
  99. }));
  100. // 统一change
  101. onParamsChange = (k, v) => {
  102. const { params } = this.state
  103. const newParams = { ...params }
  104. this.setState(
  105. {
  106. params: { ...newParams, [k]: v }
  107. }
  108. )
  109. };
  110. onOk = (cb) => {
  111. if (!this.getCheck()) {
  112. return
  113. }
  114. const { params = {} } = this.state
  115. const { detail = [] } = params
  116. // 接口内容空值判断
  117. if (!detail.length) {
  118. message.warning('压测 接口内容 不能为空!')
  119. return
  120. }
  121. // 接口 url 空值判断
  122. if (!detail.every((value) => value.url)) {
  123. message.warning('压测 接口 url 不能为空!')
  124. return
  125. }
  126. if (typeof this.props.onOk === 'function') { this.props.onOk({ ...params }) }
  127. if (typeof cb === 'function') {
  128. // eslint-disable-next-line standard/no-callback-literal
  129. cb({ ...params })
  130. }
  131. };
  132. render () {
  133. const {
  134. params = {}
  135. } = this.state
  136. const { onCancel, showModal, update } = this.props
  137. const detail = params.detail || []
  138. const header = params.header || []
  139. const settingProps = []
  140. const uploadProps = {
  141. showUploadList: false,
  142. name: 'file',
  143. action: `${yc}/schedule/task/import`,
  144. onChange: (info) => {
  145. if (info.file.status === 'done') {
  146. if (info.file.response.code !== 0) {
  147. return message.error(info.file.response.msg)
  148. }
  149. if (info.file.response.data.length > 0) {
  150. const { params } = this.state
  151. params.detail = info.file.response.data.map((url) => ({ url }))
  152. this.setState({
  153. params: params
  154. })
  155. message.success(`${info.file.name} 文件上传成功`)
  156. }
  157. } else if (info.file.status === 'error') {
  158. message.error(`${info.file.name} 文件上传失败`)
  159. }
  160. }
  161. }
  162. if (update) {
  163. settingProps.push({
  164. label: '需要新压测数据',
  165. extra: '如果你不明白这个选项是什么,请不要修改~',
  166. extraInline: true,
  167. key: 'needNew',
  168. type: 'switch',
  169. checkedChildren: '是',
  170. unCheckedChildren: '否'
  171. })
  172. }
  173. this.formSetting = [
  174. ...settingProps,
  175. {
  176. label: '任务名',
  177. key: 'name',
  178. placeholder: '请输入压测任务名',
  179. isRequired: true,
  180. type: 'input'
  181. },
  182. {
  183. label: '登录 URL',
  184. key: 'getTokenUrl',
  185. placeholder: '请输入用户登录的 URL',
  186. isRequired: true,
  187. type: 'input'
  188. },
  189. {
  190. label: '自定义 header',
  191. key: 'header',
  192. isRequired: false,
  193. render: () => {
  194. return (
  195. <div>
  196. {header.map((d, i) => (
  197. <div
  198. key={i}
  199. style={{
  200. display: 'flex',
  201. height: '40px',
  202. alignItems: 'center',
  203. flexWrap: 'wrap'
  204. }}
  205. >
  206. <Input
  207. value={d.key}
  208. style={{ width: 220, marginRight: 10 }}
  209. placeholder="键"
  210. isRequired
  211. onChange={(e) =>
  212. this.setHeader(i, e.target.value, 'key')
  213. }
  214. />
  215. <Input
  216. value={d.value}
  217. style={{ width: 220, marginRight: 10 }}
  218. placeholder="值"
  219. isRequired
  220. onChange={(e) =>
  221. this.setHeader(i, e.target.value, 'value')
  222. }
  223. />
  224. <Button
  225. type="dashed"
  226. icon="minus"
  227. style={{ marginRight: '2px' }}
  228. onClick={() => this.delHeader(i)}
  229. />
  230. {i === header.length - 1 ? (
  231. <>
  232. <Button
  233. type="dashed"
  234. icon="plus"
  235. onClick={() => this.addHeader()}
  236. />
  237. </>
  238. ) : (
  239. <>
  240. <Button
  241. type="dashed"
  242. icon="plus"
  243. style={{
  244. opacity: '0'
  245. }}
  246. />
  247. </>
  248. )}
  249. </div>
  250. ))}
  251. {!header.length && (
  252. <Button
  253. type="dashed"
  254. icon="plus"
  255. onClick={() => this.addHeader()}
  256. />
  257. )}
  258. </div>
  259. )
  260. }
  261. },
  262. {
  263. label: '压测接口',
  264. key: 'detail',
  265. isRequired: true,
  266. render: () => {
  267. return (
  268. <div>
  269. <div>
  270. <Button key="back" style={{ marginRight: 10 }}>
  271. <a href={`${yc}/schedule/task/export`}>下载</a>
  272. </Button>
  273. <Upload {...uploadProps}>
  274. <Button>导入</Button>
  275. </Upload>
  276. </div>
  277. {detail.map((d, i) => (
  278. <div
  279. key={i}
  280. style={{
  281. display: 'flex',
  282. // height: '70px',
  283. margin: '5px 0',
  284. alignItems: 'center',
  285. flexWrap: 'wrap'
  286. }}
  287. >
  288. <TextArea
  289. value={d.url}
  290. style={{ width: 450 }}
  291. autoSize={true}
  292. placeholder="请输入压测的 URL"
  293. isRequired
  294. onChange={(e) =>
  295. this.setDetail(i, e.target.value, 'url')
  296. }
  297. />
  298. &nbsp;&nbsp;
  299. {update && <span style={{ width: 130 }}>接口占比:{d.rate}&nbsp;&nbsp;</span>}
  300. <Button
  301. type="dashed"
  302. icon="minus"
  303. style={{ marginRight: '2px' }}
  304. onClick={() => this.delDetail(i)}
  305. />
  306. {i === detail.length - 1 ? (
  307. <>
  308. <Button
  309. type="dashed"
  310. icon="plus"
  311. onClick={() => this.addDetail()}
  312. />
  313. </>
  314. ) : (
  315. <>
  316. <Button
  317. type="dashed"
  318. icon="plus"
  319. style={{
  320. opacity: '0'
  321. }}
  322. />
  323. </>
  324. )}
  325. </div>
  326. ))}
  327. {!detail.length && (
  328. <Button
  329. type="dashed"
  330. icon="plus"
  331. onClick={() => this.addDetail()}
  332. />
  333. )}
  334. </div>
  335. )
  336. }
  337. }
  338. ]
  339. return (
  340. <Modal
  341. title={update ? '查看压测任务' : '添加压测任务'}
  342. visible={showModal}
  343. width={1100}
  344. onOk={this.onOk}
  345. okText={update ? '更新' : '确认'}
  346. onCancel={onCancel}
  347. >
  348. <FormItem
  349. getCheck={(cb) => {
  350. this.getCheck = cb
  351. }}
  352. onChange={this.onParamsChange}
  353. formSetting={this.formSetting}
  354. params={params}
  355. />
  356. </Modal>
  357. )
  358. }
  359. }
  360. export default Index