demandOrder.jsx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. import React from 'react';
  2. import { AutoComplete, Icon, Button, Input, InputNumber, Select, Spin, Table, message, Modal, Row, Col, DatePicker } from 'antd';
  3. import ajax from 'jquery/src/ajax/xhr.js';
  4. import $ from 'jquery/src/ajax';
  5. import moment from 'moment';
  6. import './techDemand.less';
  7. import { orderStatusList } from '../../dataDic.js';
  8. import { befoFile, getSearchUrl, getOrderStatus, companySearch } from '../../tools.js';
  9. import BatchImport from './batchImport';
  10. import throttle from '../../throttle.js';
  11. const DemandDetail = React.createClass({
  12. getInitialState() {
  13. return {
  14. visible: false,
  15. loading: false,
  16. columns: [
  17. {
  18. title: '状态',
  19. dataIndex: 'status',
  20. key: 'status',
  21. render: text => { return getOrderStatus(text) }
  22. }, {
  23. title: '操作时间',
  24. dataIndex: 'recordTimeFormattedDate',
  25. key: 'recordTimeFormattedDate',
  26. }, {
  27. title: '管理员',
  28. dataIndex: 'operator',
  29. key: 'operator',
  30. }, {
  31. title: '备注',
  32. dataIndex: 'comment',
  33. key: 'comment',
  34. }
  35. ],
  36. dataSource: [],
  37. };
  38. },
  39. loadLogs(id) {
  40. this.setState({
  41. loading: true
  42. });
  43. $.ajax({
  44. method: "get",
  45. dataType: "json",
  46. crossDomain: false,
  47. url: globalConfig.context + "/api/admin/portal/order/demandOrderLog",
  48. data: {
  49. demandOrderId: id
  50. },
  51. success: function (data) {
  52. let theArr = [];
  53. if (!data.data) {
  54. if (data.error && data.error.length) {
  55. message.warning(data.error[0].message);
  56. };
  57. } else {
  58. for (let i = 0; i < data.data.length; i++) {
  59. let thisdata = data.data[i];
  60. theArr.push({
  61. key: i,
  62. recordTime: thisdata.recordTime,
  63. status: thisdata.status,
  64. comment: thisdata.comment,
  65. operator: thisdata.operator,
  66. recordTimeFormattedDate: thisdata.recordTimeFormattedDate
  67. });
  68. };
  69. };
  70. this.setState({
  71. dataSource: theArr
  72. });
  73. }.bind(this),
  74. }).always(function () {
  75. this.setState({
  76. loading: false
  77. });
  78. }.bind(this));
  79. },
  80. handleSubmit(e) {
  81. //keyword长度判断
  82. if (this.state.orderStatus || this.state.comment || this.state.recordTime) {
  83. if (this.state.orderStatus && this.state.comment && this.state.recordTime) {
  84. } else {
  85. message.warning('请填写完整的状态流转记录!');
  86. return;
  87. };
  88. };
  89. this.setState({
  90. loading: true
  91. });
  92. $.ajax({
  93. method: "POST",
  94. dataType: "json",
  95. crossDomain: false,
  96. url: globalConfig.context + '/api/admin/portal/order/updateDemandOrder',
  97. data: {
  98. id: this.props.data.id,
  99. demandId: this.props.data.demandId,
  100. enclosureUrl: this.props.data.enclosureUrl,
  101. status: this.state.orderStatus || this.props.data.status,
  102. recordTimeFormattedDate: this.state.recordTime ? this.state.recordTime.format("YYYY-MM-DD HH:mm:ss") : undefined,
  103. comment: this.state.comment,
  104. intentionMoney: this.state.intentionMoney * 10000,
  105. contractMoney: this.state.contractMoney * 10000,
  106. commission: this.state.commission * 10000,
  107. serviceMoney: this.state.serviceMoney * 10000,
  108. }
  109. }).done(function (data) {
  110. this.setState({
  111. loading: false
  112. });
  113. if (!data.error.length) {
  114. message.success('保存成功!');
  115. this.handleOk();
  116. } else {
  117. message.warning(data.error[0].message);
  118. };
  119. }.bind(this));
  120. },
  121. handleCancel(e) {
  122. this.setState({
  123. visible: false,
  124. });
  125. this.props.closeDesc(false);
  126. },
  127. handleOk(e) {
  128. this.setState({
  129. visible: false,
  130. });
  131. this.props.closeDesc(false, true);
  132. },
  133. componentWillReceiveProps(nextProps) {
  134. if (!this.state.visible && nextProps.showDesc && nextProps.data) {
  135. this.loadLogs(nextProps.data.id);
  136. this.state.intentionMoney = nextProps.data.intentionMoney;
  137. this.state.contractMoney = nextProps.data.contractMoney;
  138. this.state.commission = nextProps.data.commission;
  139. this.state.serviceMoney = nextProps.data.serviceMoney;
  140. this.state.orderStatus = undefined;
  141. this.state.comment = undefined;
  142. this.state.recordTime = undefined;
  143. };
  144. this.state.visible = nextProps.showDesc;
  145. },
  146. render() {
  147. let theData = this.props.data;
  148. if (theData) {
  149. return (
  150. <div className="patent-desc">
  151. <Modal maskClosable={false} visible={this.state.visible}
  152. onOk={this.checkPatentProcess} onCancel={this.handleCancel}
  153. width='1200px'
  154. footer={null}
  155. title="订单详情"
  156. className="demand-order-content">
  157. <Spin spinning={this.state.loading}>
  158. <Row>
  159. <Col span={2}>订单编号:</Col>
  160. <Col span={10}>{theData.serialNumber}</Col>
  161. <Col span={2}>订单状态:</Col>
  162. <Col span={10}>{getOrderStatus(theData.status)}</Col>
  163. </Row>
  164. <Row>
  165. <Col span={2}>需求编号:</Col>
  166. <Col span={10}>{theData.demandSerialNumber}</Col>
  167. <Col span={2}>需求名称:</Col>
  168. <Col span={10}>{theData.name}</Col>
  169. </Row>
  170. <Row>
  171. <Col span={2}>需求状态:</Col>
  172. <Col span={10}>{(() => {
  173. if (theData.deletedSign == 1) {
  174. return "已删除"
  175. } else if (theData.auditStatus != 3) {
  176. return "已下架"
  177. } else {
  178. return "正常"
  179. }
  180. })()}</Col>
  181. <Col span={2}>订单所有人:</Col>
  182. <Col span={10}>{theData.theName}</Col>
  183. </Row>
  184. <Row>
  185. <Col span={2}>相关附件:</Col>
  186. <Col span={10}>
  187. {theData.enclosureUrl ?
  188. <span className="download-file">
  189. <a onClick={() => { window.open(globalConfig.context + '/api/admin/portal/order/downloadDemandOrder?id=' + theData.id) }}>科技需求订单文件</a>
  190. </span>
  191. : <span><Icon type="exclamation-circle" style={{ color: '#ffbf00', marginRight: '6px' }} />未上传!</span>}
  192. </Col>
  193. <Col span={2}>接单时间:</Col>
  194. <Col span={10}>{theData.createTimeFormattedDate}</Col>
  195. </Row>
  196. <Row>
  197. <Col span={2}>意向金:</Col>
  198. <Col span={10}>
  199. <InputNumber
  200. value={this.state.intentionMoney}
  201. onChange={(e) => { this.setState({ intentionMoney: Math.round(e * 10000) / 10000 }) }} />
  202. <span> 万元</span>
  203. </Col>
  204. <Col span={2}>合同金:</Col>
  205. <Col span={10}>
  206. <InputNumber
  207. value={this.state.contractMoney}
  208. onChange={(e) => { this.setState({ contractMoney: Math.round(e * 10000) / 10000 }) }} />
  209. <span> 万元</span>
  210. </Col>
  211. </Row>
  212. <Row>
  213. <Col span={2}>佣金:</Col>
  214. <Col span={10}>
  215. <InputNumber
  216. value={this.state.commission}
  217. onChange={(e) => { this.setState({ commission: Math.round(e * 10000) / 10000 }) }} />
  218. <span> 万元</span>
  219. </Col>
  220. <Col span={2}>服务金:</Col>
  221. <Col span={10}>
  222. <InputNumber
  223. value={this.state.serviceMoney}
  224. onChange={(e) => { this.setState({ serviceMoney: Math.round(e * 10000) / 10000 }) }} />
  225. <span> 万元</span>
  226. </Col>
  227. </Row>
  228. <p>订单状态流转记录</p>
  229. <Table size="middle" columns={this.state.columns}
  230. dataSource={this.state.dataSource}
  231. pagination={false} />
  232. <Row style={{ marginTop: '20px' }}>
  233. <Col span={2}>状态:</Col>
  234. <Col span={10}>
  235. <Select style={{ width: 160 }}
  236. value={this.state.orderStatus}
  237. onChange={(e) => { this.setState({ orderStatus: e }); }}>
  238. {(() => {
  239. let theArr = [];
  240. orderStatusList.map(function (item, i) {
  241. theArr.push(<Select.Option key={item.value}>{item.key}</Select.Option>)
  242. });
  243. return theArr;
  244. })()}
  245. </Select>
  246. </Col>
  247. <Col span={2}>时间:</Col>
  248. <Col span={10}>
  249. <DatePicker
  250. value={this.state.recordTime || null}
  251. onChange={(e) => { this.setState({ recordTime: e }); }} />
  252. </Col>
  253. </Row>
  254. <Row>
  255. <Col span={2}>备注:</Col>
  256. <Col span={20}>
  257. <Input value={this.state.comment} onChange={(e) => { this.setState({ comment: e.target.value }); }} />
  258. </Col>
  259. </Row>
  260. <Row>
  261. <Col span={2}></Col>
  262. <Col span={20}>
  263. <Button style={{ marginRight: '20px' }} type="primary" onClick={this.handleSubmit}>保存</Button>
  264. <Button className="set-submit" type="ghost" onClick={this.handleCancel}>取消</Button>
  265. </Col>
  266. </Row>
  267. </Spin>
  268. </Modal>
  269. </div>
  270. );
  271. } else {
  272. return <div></div>
  273. }
  274. },
  275. });
  276. const DemandOrderList = React.createClass({
  277. loadData(pageNo, apiUrl) {
  278. this.setState({
  279. loading: true
  280. });
  281. $.ajax({
  282. method: "get",
  283. dataType: "json",
  284. crossDomain: false,
  285. url: globalConfig.context + (apiUrl || this.props['data-listApiUrl']),
  286. data: {
  287. pageNo: pageNo || 1,
  288. pageSize: this.state.pagination.pageSize,
  289. status: this.state.status,
  290. username: ((apiUrl || this.props['data-listApiUrl']).indexOf('org') != -1) ? null : this.state.searchName,
  291. unitName: ((apiUrl || this.props['data-listApiUrl']).indexOf('org') != -1) ? this.state.searchName : null
  292. },
  293. success: function (data) {
  294. let theArr = [];
  295. if (!data.data || !data.data.list) {
  296. if (data.error && data.error.length) {
  297. message.warning(data.error[0].message);
  298. };
  299. } else {
  300. for (let i = 0; i < data.data.list.length; i++) {
  301. let thisdata = data.data.list[i];
  302. theArr.push({
  303. key: i,
  304. id: thisdata.id, //线索单/意向单ID
  305. serialNumber: thisdata.serialNumber, //线索单/意向单编号
  306. demandId: thisdata.demandId, //科技需求ID
  307. createTime: thisdata.createTime,
  308. enclosureUrl: thisdata.enclosureUrl,
  309. status: thisdata.status, //线索单/意向单状态
  310. intentionMoney: thisdata.intentionMoney / 10000, //意向金
  311. contractMoney: thisdata.contractMoney / 10000, //合同金
  312. commission: thisdata.commission / 10000, //佣金
  313. serviceMoney: thisdata.serviceMoney / 10000, //服务金
  314. name: thisdata.name, //需求名称,
  315. demandSerialNumber: thisdata.demandSerialNumber, //科技需求编号
  316. deletedSign: thisdata.deletedSign, //科技需求删除标记
  317. auditStatus: thisdata.auditStatus, //科技需求审核状态
  318. theName: thisdata.username || thisdata.unitName, //个人用户名称
  319. uid: thisdata.uid, //个人用户ID
  320. createTimeFormattedDate: thisdata.createTimeFormattedDate, //接单时间
  321. });
  322. };
  323. this.state.pagination.current = data.data.pageNo;
  324. this.state.pagination.total = data.data.totalCount;
  325. }
  326. this.setState({
  327. dataSource: theArr,
  328. pagination: this.state.pagination
  329. });
  330. }.bind(this),
  331. }).always(function () {
  332. this.setState({
  333. loading: false
  334. });
  335. }.bind(this));
  336. },
  337. getInitialState() {
  338. return {
  339. selectedRowKeys: [],
  340. selectedRows: [],
  341. searchData: [],
  342. loading: false,
  343. pagination: {
  344. defaultCurrent: 1,
  345. defaultPageSize: 10,
  346. showQuickJumper: true,
  347. pageSize: 10,
  348. onChange: function (page) {
  349. this.loadData(page);
  350. }.bind(this),
  351. showTotal: function (total) {
  352. return '共' + total + '条数据';
  353. }
  354. },
  355. columns: [
  356. {
  357. title: '编号',
  358. dataIndex: 'serialNumber',
  359. key: 'serialNumber',
  360. }, {
  361. title: '需求名称',
  362. dataIndex: 'name',
  363. key: 'name',
  364. }, {
  365. title: '需求编号',
  366. dataIndex: 'demandSerialNumber',
  367. key: 'demandSerialNumber',
  368. }, {
  369. title: '订单所有人',
  370. dataIndex: 'theName',
  371. key: 'theName',
  372. }, {
  373. title: '订单状态',
  374. dataIndex: 'auditStatus',
  375. key: 'auditStatus',
  376. render: (text, record) => {
  377. if (record.deletedSign == 1) {
  378. return "已删除"
  379. } else if (record.auditStatus != 3) {
  380. return "已下架"
  381. } else {
  382. return "正常"
  383. }
  384. }
  385. }, {
  386. title: '流程状态',
  387. dataIndex: 'status',
  388. key: 'status',
  389. render: (text, record) => { return getOrderStatus(text); }
  390. }, {
  391. title: '意向金(万元)',
  392. dataIndex: 'intentionMoney',
  393. key: 'intentionMoney',
  394. }, {
  395. title: '合同金(万元)',
  396. dataIndex: 'contractMoney',
  397. key: 'contractMoney',
  398. }, {
  399. title: '佣金(万元)',
  400. dataIndex: 'commission',
  401. key: 'commission',
  402. }, {
  403. title: '服务金(万元)',
  404. dataIndex: 'serviceMoney',
  405. key: 'serviceMoney',
  406. }, {
  407. title: '接单时间',
  408. dataIndex: 'createTimeFormattedDate',
  409. key: 'createTimeFormattedDate',
  410. }
  411. ],
  412. dataSource: [],
  413. };
  414. },
  415. handleSearch(e) {
  416. if (this.props['data-detailApiUrl'].indexOf('org') != -1) {
  417. $.ajax({
  418. method: "get",
  419. dataType: "json",
  420. crossDomain: false,
  421. url: globalConfig.context + "/api/admin/achievement/orgOwner",
  422. data: { name: e },
  423. success: function (data) {
  424. let theArr = [];
  425. let theObj = {};
  426. if (!data.data) {
  427. if (data.error && data.error.length) {
  428. message.warning(data.error[0].message);
  429. };
  430. } else if (!$.isEmptyObject(data.data)) {
  431. data.data.map(function (item) {
  432. theArr.push(item.unitName);
  433. theObj[item.unitName] = item.uid;
  434. });
  435. };
  436. this.setState({
  437. searchData: theArr,
  438. dataSourceObj: theObj
  439. });
  440. }.bind(this),
  441. });
  442. } else {
  443. $.ajax({
  444. method: "get",
  445. dataType: "json",
  446. crossDomain: false,
  447. url: globalConfig.context + "/api/admin/achievement/userOwner",
  448. data: { name: e },
  449. success: function (data) {
  450. let theArr = [];
  451. let theObj = {};
  452. if (!data.data) {
  453. if (data.error && data.error.length) {
  454. message.warning(data.error[0].message);
  455. };
  456. } else if (!$.isEmptyObject(data.data)) {
  457. for (let item in data.data) {
  458. theArr.push(data.data[item]);
  459. theObj[data.data[item]] = item;
  460. };
  461. };
  462. this.setState({
  463. dataSource: theArr,
  464. dataSourceObj: theObj
  465. });
  466. }.bind(this),
  467. });
  468. };
  469. },
  470. componentWillMount() {
  471. this.state.therottleSearch = throttle(this.handleSearch, 1000, { leading: false }).bind(this);
  472. let theArr = [], typeArr = [];
  473. orderStatusList.map(function (item) {
  474. theArr.push(
  475. <Select.Option value={item.value} key={item.key}>{item.key}</Select.Option>
  476. )
  477. });
  478. this.state.demandTypeOption = typeArr;
  479. this.state.orderStatusOption = theArr;
  480. // if (window.location.search) {
  481. // let theObj = getSearchUrl(window.location.search);
  482. // if (theObj.rid) {
  483. // theObj.id = theObj.rid;
  484. // if (theObj.rid != 'null') {
  485. // this.tableRowClick(theObj);
  486. // };
  487. // };
  488. // };
  489. this.loadData();
  490. },
  491. componentWillReceiveProps(nextProps) {
  492. if (this.props['data-listApiUrl'] != nextProps['data-listApiUrl']) {
  493. this.state.selectedRowKeys = [];
  494. this.state.selectedRows = [];
  495. this.state.status = undefined;
  496. this.state.searchName = null;
  497. this.state.searchData = [];
  498. this.loadData(null, nextProps['data-listApiUrl']);
  499. };
  500. },
  501. tableRowClick(record, index) {
  502. this.state.RowData = record;
  503. this.setState({
  504. showDesc: true
  505. });
  506. },
  507. delectRow() {
  508. let deletedIds = [];
  509. for (let idx = 0; idx < this.state.selectedRows.length; idx++) {
  510. let rowItem = this.state.selectedRows[idx];
  511. if (rowItem.id) {
  512. deletedIds.push(rowItem.id)
  513. };
  514. };
  515. this.setState({
  516. selectedRowKeys: [],
  517. loading: deletedIds.length > 0
  518. });
  519. $.ajax({
  520. method: "POST",
  521. dataType: "json",
  522. crossDomain: false,
  523. url: globalConfig.context + "/api/admin/demand/delete",
  524. data: {
  525. ids: deletedIds
  526. }
  527. }).done(function (data) {
  528. if (!data.error.length) {
  529. message.success('删除成功!');
  530. this.setState({
  531. loading: false,
  532. });
  533. } else {
  534. message.warning(data.error[0].message);
  535. };
  536. this.loadData();
  537. }.bind(this));
  538. },
  539. addClick() {
  540. this.state.RowData = {};
  541. this.setState({
  542. showDesc: true
  543. });
  544. },
  545. closeDesc(e, s) {
  546. this.state.showDesc = e;
  547. if (s) {
  548. this.loadData();
  549. };
  550. },
  551. search() {
  552. this.loadData();
  553. },
  554. reset() {
  555. this.state.searchName = undefined;
  556. this.state.status = undefined;
  557. this.state.sert
  558. this.loadData();
  559. },
  560. render() {
  561. const rowSelection = {
  562. selectedRowKeys: this.state.selectedRowKeys,
  563. onChange: (selectedRowKeys, selectedRows) => {
  564. this.setState({
  565. selectedRows: selectedRows.splice(-1),
  566. selectedRowKeys: selectedRowKeys.splice(-1)
  567. });
  568. }
  569. };
  570. const hasSelected = this.state.selectedRowKeys.length > 0;
  571. return (
  572. <div className="user-content" >
  573. <div className="content-title">
  574. {this.props['data-listApiUrl'].indexOf('org') == -1 ? <span>个人需求订单管理</span> : <span>组织需求订单管理</span>}
  575. </div>
  576. <div className="user-search">
  577. <Select placeholder="选择状态" style={{ width: 160 }}
  578. value={this.state.status}
  579. onChange={(e) => { this.setState({ status: e }) }}>
  580. {this.state.orderStatusOption}
  581. </Select>
  582. <AutoComplete
  583. dataSource={this.state.searchData}
  584. value={this.state.searchName}
  585. style={{ width: 200 }}
  586. onSearch={this.state.therottleSearch}
  587. placeholder="输入订单所有人名称"
  588. onChange={(e) => {
  589. this.setState({ searchName: e });
  590. }} />
  591. <Button type="primary" onClick={this.search}>搜索</Button>
  592. <Button onClick={this.reset}>重置</Button>
  593. </div>
  594. <div className="patent-table">
  595. <Spin spinning={this.state.loading}>
  596. <Table size="middle" columns={this.state.columns}
  597. dataSource={this.state.dataSource}
  598. //rowSelection={rowSelection}
  599. pagination={this.state.pagination}
  600. style={{
  601. cursor: 'pointer',
  602. }}
  603. onRowClick={this.tableRowClick} />
  604. </Spin>
  605. </div>
  606. <DemandDetail
  607. data={this.state.RowData}
  608. showDesc={this.state.showDesc}
  609. closeDesc={this.closeDesc} />
  610. </div >
  611. );
  612. }
  613. });
  614. export default DemandOrderList;
  615. // <Button style={{ background: "#3fcf9e", border: "none", color: "#fff" }}
  616. // disabled={!hasSelected}
  617. // onClick={this.delectRow}>删除<Icon type="minus" /></Button>