index.jsx 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. import React, { Component } from "react";
  2. import { Button, Modal, message, Input, Form, Spin, } from "antd";
  3. import $ from "jquery/src/ajax";
  4. import "./index.less";
  5. import { splitUrl } from '@/tools';
  6. import ImgList from "../imgList";
  7. /**
  8. *
  9. */
  10. const PicturesWall = React.createClass({
  11. getInitialState() {
  12. return {
  13. previewVisible: false,
  14. previewImage: "",
  15. fileList: this.props.pictureUrl,
  16. };
  17. },
  18. getDefaultProps() {
  19. return {
  20. changeClick: this.modifyChange,
  21. };
  22. },
  23. handleCancel() {
  24. this.setState({ previewVisible: false });
  25. },
  26. handlePreview(file) {
  27. this.setState({
  28. previewImage: file.url || file.thumbUrl,
  29. previewVisible: true,
  30. });
  31. },
  32. handleChange(info) {
  33. let fileList = info.fileList;
  34. this.setState({ fileList });
  35. this.props.fileList(fileList);
  36. },
  37. componentWillReceiveProps(nextProps) {
  38. this.state.fileList = nextProps.pictureUrl;
  39. },
  40. render() {
  41. const { fileList } = this.state;
  42. return (
  43. <div style={{ display: "inline-block" }}>
  44. <ImgList
  45. domId={this.props.domId}
  46. uploadConfig={{
  47. action: globalConfig.context + "/api/admin/orderProject/uploadStopFile",
  48. data: { sign: "projectStopFile" },
  49. multiple: true,
  50. listType: "picture-card",
  51. }}
  52. onChange={(infor) => {
  53. this.handleChange(infor);
  54. }}
  55. fileList={fileList}
  56. />
  57. </div>
  58. );
  59. },
  60. });
  61. class MySuspend extends Component {
  62. constructor(props) {
  63. super(props);
  64. this.state = {
  65. reason: "", //原因
  66. orgCodeUrl: [], //附件
  67. loading: false,
  68. logList: [], //日志
  69. emVisible: false, //审核弹窗
  70. emReason: "", //审核说明
  71. };
  72. this.onOks = this.onOks.bind(this);
  73. this.getOrgCodeUrl = this.getOrgCodeUrl.bind(this);
  74. }
  75. componentDidMount() {
  76. const { rowData, type, again = false } = this.props
  77. type == "details" && !!rowData && !!rowData.id && this.getLog(rowData.id)
  78. if (again) {
  79. this.setState({
  80. reason: rowData.reason,
  81. orgCodeUrl: splitUrl(rowData.annexUrl, ",", globalConfig.avatarHost + "/upload"),
  82. })
  83. }
  84. }
  85. // 日志
  86. getLog(id) {
  87. this.setState({
  88. loading: true,
  89. });
  90. $.ajax({
  91. method: "get",
  92. dataType: "json",
  93. url: globalConfig.context + "/api/admin/orderProject/projectStopList",
  94. data: {
  95. taskStopId: id,
  96. },
  97. success: function (data) {
  98. if (data.error.length === 0) {
  99. this.setState({
  100. logList: data.data || [],
  101. });
  102. } else {
  103. message.warning(data.error[0].message);
  104. }
  105. }.bind(this),
  106. }).always(
  107. function () {
  108. this.setState({
  109. loading: false,
  110. });
  111. }.bind(this)
  112. );
  113. }
  114. // 确定
  115. onOks() {
  116. const { selectedRowKeys, subClose, title } = this.props
  117. let annexUrl = []
  118. if (this.state.orgCodeUrl.length) {
  119. let annexArr = [];
  120. this.state.orgCodeUrl.map(function (item) {
  121. if (
  122. item.response &&
  123. item.response.data &&
  124. item.response.data.length
  125. ) {
  126. annexArr.push(item.response.data);
  127. }
  128. });
  129. annexUrl = annexArr.join(",");
  130. }
  131. if (typeof annexUrl !== "string") {
  132. message.warning("请上传附件!");
  133. return
  134. }
  135. if (!this.state.reason) {
  136. message.warning("请填写原因!");
  137. return
  138. }
  139. if (!this.state.reason.replace(/\s+/g, '')) {
  140. message.warning("请填写原因!");
  141. return;
  142. }
  143. this.setState({
  144. loading: true,
  145. });
  146. let infor = {
  147. ids: selectedRowKeys.toString(),
  148. type: title == "项目重启" ? 1 : 0, //0=项目暂停,1=项目重启
  149. reason: this.state.reason, //原因
  150. annexUrl: annexUrl.length ? annexUrl : undefined,//附件,
  151. }
  152. $.ajax({
  153. method: "POST",
  154. dataType: "json",
  155. crossDomain: false,
  156. url: globalConfig.context + "/api/admin/orderProject/addProjectStop",
  157. data: infor,
  158. }).done(
  159. function (data) {
  160. this.setState({
  161. loading: false,
  162. });
  163. if (!data.error.length) {
  164. message.success("操作成功!");
  165. subClose()
  166. } else {
  167. message.warning(data.error[0].message);
  168. }
  169. }.bind(this)
  170. );
  171. }
  172. // 重新
  173. onAgain() {
  174. const { subClose, title, rowData } = this.props
  175. let annexUrl = []
  176. if (this.state.orgCodeUrl.length) {
  177. let annexArr = [];
  178. this.state.orgCodeUrl.map(function (item) {
  179. if (
  180. item.response &&
  181. item.response.data &&
  182. item.response.data.length
  183. ) {
  184. annexArr.push(item.response.data);
  185. }
  186. });
  187. annexUrl = annexArr.join(",");
  188. }
  189. if (typeof annexUrl !== "string") {
  190. message.warning("请上传附件!");
  191. return
  192. }
  193. if (!this.state.reason) {
  194. message.warning("请填写原因!");
  195. return
  196. }
  197. if (!this.state.reason.replace(/\s+/g, '')) {
  198. message.warning("请填写原因!");
  199. return;
  200. }
  201. this.setState({
  202. loading: true,
  203. });
  204. let infor = {
  205. stopId: rowData.id, //暂停编号
  206. type: title == "项目重启" ? 1 : 0, //0=项目暂停,1=项目重启
  207. reason: this.state.reason, //原因
  208. annexUrl: annexUrl.length ? annexUrl : undefined,//附件,
  209. }
  210. $.ajax({
  211. method: "POST",
  212. dataType: "json",
  213. crossDomain: false,
  214. url: globalConfig.context + "/api/admin/orderProject/updateProjectStop",
  215. data: infor,
  216. }).done(
  217. function (data) {
  218. this.setState({
  219. loading: false,
  220. });
  221. if (!data.error.length) {
  222. message.success("重新发起成功!");
  223. subClose()
  224. } else {
  225. message.warning(data.error[0].message);
  226. }
  227. }.bind(this)
  228. );
  229. }
  230. // 图片添加
  231. getOrgCodeUrl(e) {
  232. this.setState({ orgCodeUrl: e });
  233. }
  234. // 关闭审核弹窗
  235. emCancel() {
  236. const { subClose } = this.props
  237. this.setState({
  238. emVisible: false,
  239. emReason: "",
  240. }, () => {
  241. subClose()
  242. })
  243. }
  244. // 项目审核
  245. examineProjectStop(status) {
  246. if (!this.state.emReason) {
  247. message.warning("请填写审核说明~");
  248. return;
  249. }
  250. if (!this.state.emReason.replace(/\s+/g, '')) {
  251. message.warning("请填写审核说明~");
  252. return;
  253. }
  254. this.setState({
  255. loading: true,
  256. });
  257. $.ajax({
  258. method: "POST",
  259. dataType: "json",
  260. crossDomain: false,
  261. url: globalConfig.context + "/api/admin/orderProject/examineProjectStop",
  262. data: {
  263. taskStopId: this.props.rowData.id,
  264. reason: this.state.emReason,
  265. status,
  266. },
  267. }).done(
  268. function (data) {
  269. if (!data.error.length) {
  270. this.setState({
  271. loading: false,
  272. })
  273. message.success("审核成功!");
  274. this.emCancel()
  275. } else {
  276. message.warning(data.error[0].message);
  277. }
  278. }.bind(this)
  279. );
  280. }
  281. render() {
  282. const { visible, title, orderNo, userName, contractNo, isApproved = false,
  283. subClose, selectedRows, type, reason, annexUrl, rowData,
  284. } = this.props
  285. const { logList } = this.state
  286. const FormItem = Form.Item;
  287. const formItemLayout = {
  288. labelCol: { span: 3 },
  289. wrapperCol: { span: 20 },
  290. };
  291. return (
  292. <Modal
  293. maskClosable={false}
  294. visible={visible}
  295. width={"700px"}
  296. title=""
  297. footer=""
  298. onCancel={subClose}
  299. >
  300. <Spin spinning={this.state.loading}>
  301. <div className="clearfix">
  302. <div className="tittle">{title}</div>
  303. <div style={{ marginLeft: 20 }}>
  304. <div style={{ marginBottom: 10 }}>
  305. {type != "details" && "请您确定,是否将"}
  306. 订单号:{orderNo},客户:{userName},合同编号:{contractNo}
  307. {type != "details" && ("的项目进行" + (title == "项目重启" ? "重启" : "暂停"))}
  308. </div>
  309. <div>{title == "项目重启" ? "重启" : "暂停"}项目清单:</div>
  310. {
  311. selectedRows.length > 0 && selectedRows.map((item, index) =>
  312. <div
  313. key={item.id}
  314. style={{ marginLeft: 20 }}
  315. >{index + 1}{"、" + item.commodityName + "-" + item.id}</div>
  316. )
  317. }
  318. </div>
  319. <Form>
  320. <div className="clearfix" style={{ marginTop: 20 }}>
  321. {
  322. type == "details" ?
  323. <FormItem
  324. {...formItemLayout}
  325. label={title == "项目重启" ? "重启原因" : "暂停原因"}
  326. >
  327. {reason}
  328. </FormItem> :
  329. <FormItem
  330. {...formItemLayout}
  331. label={<span><span style={{ color: "red" }}>*</span>{title == "项目重启" ? "重启原因" : "暂停原因"}</span>}
  332. >
  333. <Input
  334. type="textarea"
  335. placeholder=""
  336. autosize={{ minRows: 3 }}
  337. value={this.state.reason}
  338. onChange={(e) => {
  339. this.setState({ reason: e.target.value });
  340. }}
  341. />
  342. <span>
  343. 点击“确定{title == "项目重启" ? "重启" : "暂停"}”,
  344. 审核通过后,项目状态更改为“{title == "项目重启" ? "正常" : "暂停"}”,
  345. 技术人员将暂停此项目的相关服务!
  346. </span>
  347. </FormItem>
  348. }
  349. </div>
  350. <div className="clearfix">
  351. {
  352. type == "details" ?
  353. <FormItem
  354. {...formItemLayout}
  355. label="附件"
  356. >
  357. <ImgList fileList={splitUrl(annexUrl, ",", globalConfig.avatarHost + "/upload")} domId={"details"} />
  358. </FormItem> :
  359. <FormItem
  360. {...formItemLayout}
  361. label={<span><span style={{ color: "red" }}>*</span>上传附件</span>}
  362. >
  363. <PicturesWall
  364. fileList={this.getOrgCodeUrl}
  365. pictureUrl={this.state.orgCodeUrl}
  366. />
  367. <p>图片建议:要清晰。</p>
  368. <p style={{ color: "red" }}>可上传与客户协议或截图等信息</p>
  369. </FormItem>
  370. }
  371. </div>
  372. {
  373. type != "details" &&
  374. <div className="clearfix">
  375. <FormItem
  376. wrapperCol={{ span: 12, offset: 7 }}
  377. className="half-middle"
  378. >
  379. <Button
  380. className="submitSave"
  381. type="primary"
  382. onClick={() => {
  383. this.props.again
  384. ? this.onAgain()
  385. : this.onOks()
  386. }}
  387. >
  388. {
  389. this.props.again
  390. ? "重新发起"
  391. : (title == "项目重启" ? "确定重启" : "确定暂停")
  392. }
  393. </Button>
  394. <Button
  395. className="submitSave"
  396. type="primary"
  397. onClick={subClose}
  398. >
  399. 取消
  400. </Button>
  401. </FormItem>
  402. </div>
  403. }
  404. {
  405. // 日志
  406. type == "details" &&
  407. <div style={{ marginLeft: 20, marginBottom: 20 }}>
  408. {
  409. logList.map((item) =>
  410. <div key={item.id}>
  411. {item.createName + ":" + item.createTimes + " "}
  412. <span style={{ color: ["", "green", "red"][item.status], fontWeight: "bold" }}>
  413. {" " + ["【发起】", "【通过】", "【拒绝】"][item.status] + " "}
  414. </span>
  415. {"备注:" + item.reason}
  416. </div>
  417. )
  418. }
  419. </div>
  420. }
  421. {
  422. !!rowData && rowData.stopStatus == 0 && isApproved &&
  423. <div className="clearfix">
  424. <FormItem
  425. wrapperCol={{ span: 12, offset: 10 }}
  426. className="half-middle"
  427. >
  428. <Button
  429. type="primary"
  430. onClick={() => {
  431. this.setState({
  432. emVisible: true,
  433. })
  434. }}
  435. >
  436. 审核
  437. </Button>
  438. </FormItem>
  439. </div>
  440. }
  441. </Form>
  442. </div>
  443. </Spin >
  444. {
  445. // 项目审核
  446. this.state.emVisible &&
  447. <Modal
  448. visible={this.state.emVisible}
  449. width="500px"
  450. title="项目审核"
  451. footer=""
  452. onCancel={() => { this.setState({ emVisible: false }) }}
  453. >
  454. <Form>
  455. <Spin spinning={this.state.loading}>
  456. <FormItem
  457. labelCol={{ span: 5 }}
  458. wrapperCol={{ span: 16 }}
  459. label={
  460. <span>
  461. <strong style={{ color: "#f00" }}>*</strong>
  462. 备注
  463. </span>
  464. }
  465. >
  466. <Input
  467. type="textarea"
  468. rows={4}
  469. placeholder="请填写审核说明"
  470. value={this.state.emReason}
  471. onChange={(e) => {
  472. this.setState({ emReason: e.target.value });
  473. }}
  474. />
  475. </FormItem>
  476. <FormItem wrapperCol={{ span: 12, offset: 5 }}>
  477. <Button
  478. type="primary"
  479. onClick={() => { this.examineProjectStop(1) }}
  480. style={{ marginRight: 20 }}
  481. >
  482. 同意
  483. </Button>
  484. <Button
  485. type="primary"
  486. onClick={() => { this.examineProjectStop(2) }}
  487. style={{ marginRight: 20 }}
  488. >
  489. 驳回
  490. </Button>
  491. <Button
  492. type="default"
  493. onClick={() => { this.setState({ emVisible: false }) }}
  494. >
  495. 取消
  496. </Button>
  497. </FormItem>
  498. </Spin>
  499. </Form>
  500. </Modal>
  501. }
  502. </Modal >
  503. );
  504. }
  505. }
  506. export default MySuspend;