index.jsx 15 KB

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