demandDesc.jsx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. import React from 'react';
  2. import { Icon, Modal, message, Spin, Button, Row, Col, Upload, Tooltip, Tag, Input, Table } from 'antd';
  3. import '../portal.less';
  4. import ajax from 'jquery/src/ajax/xhr.js';
  5. import $ from 'jquery/src/ajax';
  6. import { getIndustryCategory } from '../../DicIndustryList.js';
  7. import { splitUrl, getDemandType, beforeUploadFile, getOrderStatus } from '../../tools.js';
  8. import ImgList from "../../common/imgList";
  9. const DemandDetail = React.createClass({
  10. getInitialState() {
  11. return {
  12. visible: false,
  13. loading: false,
  14. buttonLoading: false,
  15. dataSource: [],
  16. orderVisible: false,
  17. fileList: false,
  18. tags: [],
  19. pictureUrl: [],
  20. columns: [
  21. {
  22. title: '状态',
  23. dataIndex: 'status',
  24. key: 'status',
  25. render: (text) => { return getOrderStatus(text) }
  26. }, {
  27. title: '处理时间',
  28. dataIndex: 'recordTimeFormattedDate',
  29. key: 'recordTimeFormattedDate',
  30. }, {
  31. title: '备注',
  32. dataIndex: 'comment',
  33. key: 'comment',
  34. }
  35. ]
  36. };
  37. },
  38. handleCancel(e) {
  39. this.props.closeDesc(false);
  40. },
  41. loadData(id) {
  42. this.setState({
  43. loading: true
  44. });
  45. $.ajax({
  46. method: "get",
  47. dataType: "json",
  48. crossDomain: false,
  49. url: globalConfig.context + '/api/user/portal/demandDetail',
  50. data: {
  51. id: id
  52. },
  53. success: function (data) {
  54. let thisData = data.data;
  55. if (!thisData) {
  56. if (data.error && data.error.length) {
  57. message.warning(data.error[0].message);
  58. };
  59. thisData = {};
  60. };
  61. this.setState({
  62. data: thisData,
  63. tags: thisData.keyword ? thisData.keyword.split(",") : [],
  64. pictureUrl: thisData.pictureUrl ? splitUrl(thisData.pictureUrl, ',', globalConfig.avatarHost + '/upload') : []
  65. });
  66. }.bind(this),
  67. }).always(function () {
  68. this.setState({
  69. loading: false
  70. });
  71. }.bind(this));
  72. },
  73. loadLogsData(id) {
  74. this.setState({
  75. loading: true
  76. });
  77. $.ajax({
  78. method: "get",
  79. dataType: "json",
  80. crossDomain: false,
  81. url: globalConfig.context + '/api/user/portal/order/demandOrderLog',
  82. data: {
  83. demandOrderId: id
  84. },
  85. success: function (data) {
  86. let thisData = data.data, theArr = [], _me = this;
  87. if (!thisData) {
  88. if (data.error && data.error.length) {
  89. message.warning(data.error[0].message);
  90. };
  91. } else {
  92. thisData.map(function (item, i) {
  93. theArr.push({
  94. key: i,
  95. recordTime: item.recordTime,
  96. recordTimeFormattedDate: item.recordTimeFormattedDate,
  97. status: item.status,
  98. comment: item.comment
  99. });
  100. _me.state.logsOrderStatus = item.status;
  101. });
  102. };
  103. this.setState({
  104. dataSource: theArr
  105. });
  106. }.bind(this),
  107. }).always(function () {
  108. this.setState({
  109. loading: false
  110. });
  111. }.bind(this));
  112. },
  113. interestClick() {
  114. this.setState({
  115. loading: true
  116. });
  117. $.ajax({
  118. method: "post",
  119. dataType: "json",
  120. crossDomain: false,
  121. url: globalConfig.context + '/api/user/portal/demandInterest',
  122. data: {
  123. id: this.props.data.id
  124. },
  125. success: function (data) {
  126. if (data.error && data.error.length) {
  127. message.warning(data.error[0].message);
  128. } else {
  129. this.loadData(this.props.data.id);
  130. };
  131. }.bind(this),
  132. }).always(function () {
  133. this.setState({
  134. loading: false
  135. });
  136. }.bind(this));;
  137. },
  138. cancelInterestClick() {
  139. this.setState({
  140. loading: true
  141. });
  142. $.ajax({
  143. method: "post",
  144. dataType: "json",
  145. crossDomain: false,
  146. url: globalConfig.context + '/api/user/portal/demandCancelInterest',
  147. data: {
  148. id: this.state.data.demandInterestId
  149. },
  150. success: function (data) {
  151. if (data.error && data.error.length) {
  152. message.warning(data.error[0].message);
  153. } else {
  154. this.loadData(this.props.data.id);
  155. };
  156. }.bind(this),
  157. }).always(function () {
  158. this.setState({
  159. loading: false
  160. });
  161. }.bind(this));;
  162. },
  163. handleSubmit() {
  164. this.setState({
  165. buttonLoading: true
  166. });
  167. $.ajax({
  168. method: "post",
  169. dataType: "json",
  170. crossDomain: false,
  171. url: globalConfig.context + '/api/user/portal/order/orderDemand',
  172. data: {
  173. demandId: this.state.data.id,
  174. enclosureUrl: this.state.enclosureUrl,
  175. comment: this.state.comment
  176. },
  177. success: function (data) {
  178. if (data.error && data.error.length) {
  179. message.warning(data.error[0].message);
  180. } else { message.success("提交成功!") };
  181. }.bind(this),
  182. }).always(function () {
  183. this.loadData(this.state.data.id);
  184. this.setState({
  185. orderVisible: false,
  186. buttonLoading: false
  187. });
  188. }.bind(this));
  189. },
  190. cancelSubmit() {
  191. this.setState({
  192. buttonLoading: true
  193. });
  194. $.ajax({
  195. method: "post",
  196. dataType: "json",
  197. crossDomain: false,
  198. url: globalConfig.context + '/api/user/portal/order/demandShutdown',
  199. data: {
  200. id: this.state.data.demandOrderId
  201. },
  202. success: function (data) {
  203. if (data.error && data.error.length) {
  204. message.warning(data.error[0].message);
  205. } else { message.success("撤销成功!") };
  206. }.bind(this),
  207. }).always(function () {
  208. this.loadData(this.state.data.id);
  209. this.setState({
  210. buttonLoading: false
  211. });
  212. }.bind(this));
  213. },
  214. componentWillReceiveProps(nextProps) {
  215. if (!this.props.showDesc && nextProps.showDesc) {
  216. if (nextProps.data.id) {
  217. this.loadData(nextProps.data.id);
  218. if (nextProps.data.orderId) {
  219. this.loadLogsData(nextProps.data.orderId)
  220. }
  221. } else {
  222. this.state.data = {};
  223. this.state.tags = [];
  224. this.state.pictureUrl = [];
  225. };
  226. };
  227. },
  228. render() {
  229. const theData = this.state.data || {};
  230. if (this.props.data) {
  231. return (
  232. <Modal maskClosable={false}
  233. visible={this.props.showDesc}
  234. onCancel={this.handleCancel}
  235. title={<div className="interest clearfix">
  236. <span>需求详情</span>
  237. {theData.demandInterestId ? <a onClick={this.cancelInterestClick}><Icon type="heart" /> 不感兴趣</a>
  238. : <a onClick={this.interestClick}><Icon type="heart-o" /> 感兴趣</a>}
  239. </div>}
  240. width='1000px'
  241. footer=''
  242. className="portal-desc-content">
  243. <Spin spinning={this.state.loading} className="portal-desc">
  244. <Row>
  245. <Col span={4}>编号</Col>
  246. <Col span={8}>{theData.serialNumber}</Col>
  247. <Col span={4}>名称</Col>
  248. <Col span={8}>{theData.name}</Col>
  249. </Row>
  250. <Row>
  251. <Col span={4}>数据类别</Col>
  252. <Col span={8}>
  253. {(() => {
  254. switch (theData.dataCategory) {
  255. case "0":
  256. return <span>个人需求</span>;
  257. case "1":
  258. return <span>单位需求</span>;
  259. }
  260. })()}
  261. </Col>
  262. <Col span={4}>需求类型</Col>
  263. <Col span={8}>{getDemandType(theData.demandType)}</Col>
  264. </Row>
  265. <Row>
  266. <Col span={4}>应用领域</Col>
  267. <Col span={8}>{getIndustryCategory(theData.industryCategoryA, theData.industryCategoryB)}</Col>
  268. <Col span={4}>有效期限</Col>
  269. <Col span={8}>{theData.releaseDateFormattedDate}</Col>
  270. </Row>
  271. <Row>
  272. <Col span={4}>关键词</Col>
  273. <Col span={20}>
  274. {this.state.tags.map((tag) => {
  275. return <Tooltip key={tag} title={tag}>
  276. <Tag key={tag}>{tag}</Tag>
  277. </Tooltip>;
  278. })}
  279. </Col>
  280. </Row>
  281. <Row>
  282. <Col span={4}>问题说明</Col>
  283. <Col span={20}>{theData.problemDes}</Col>
  284. </Row>
  285. <Row>
  286. <Col span={4}>技术指标要求</Col>
  287. <Col span={20}>{theData.technicalRequirements}</Col>
  288. </Row>
  289. <Row>
  290. <Col span={4}>需求相关文件(图片)</Col>
  291. <Col span={20}>
  292. <div className="clearfix">
  293. <Upload
  294. listType="picture-card"
  295. fileList={this.state.pictureUrl}
  296. onPreview={(file) => {
  297. this.setState({
  298. previewImage: file.url || file.thumbUrl,
  299. previewVisible: true,
  300. });
  301. }} />
  302. {/*<div style={{paddingTop:'10px',paddingBottom:'10px'}}>*/}
  303. {/* <ImgList fileList={this.state.pictureUrl} ItemWidth={'96px'}/>*/}
  304. {/*</div>*/}
  305. <Modal maskClosable={false} footer={null}
  306. visible={this.state.previewVisible}
  307. onCancel={() => { this.setState({ previewVisible: false }) }}>
  308. <img alt="" style={{ width: '100%' }} src={this.state.previewImage || ''} />
  309. </Modal>
  310. </div>
  311. </Col>
  312. </Row>
  313. <Row>
  314. <Col span={4}>需求相关文件(文本)</Col>
  315. <Col span={20}>
  316. {theData.textFileUrl ?
  317. <span className="download-file">
  318. <a onClick={() => { window.open(globalConfig.context + '/api/user/demand/download?id=' + theData.id + '&sign=demand_maturity_text_file') }}>需求文件(文本文件)</a>
  319. </span>
  320. : <span><Icon type="exclamation-circle" style={{ color: '#ffbf00', marginRight: '6px' }} />未上传!</span>}
  321. </Col>
  322. </Row>
  323. <Row>
  324. <Col span={4}>需求文件(视频地址)</Col>
  325. <Col span={20}>{theData.videoUrl}</Col>
  326. </Row>
  327. <Row>
  328. <Col span={4}>雇佣方名称</Col>
  329. <Col span={8}>{theData.employerName}</Col>
  330. <Col span={4}>固定周期</Col>
  331. <Col span={8}>{theData.fixedCycle}</Col>
  332. </Row>
  333. <Row>
  334. <Col span={4}>固定人数</Col>
  335. <Col span={8}>{theData.peopleNumber}</Col>
  336. <Col span={4}>预算价格</Col>
  337. <Col span={8}>{theData.budgetCost}</Col>
  338. </Row>
  339. <Row>
  340. <Col span={4}>固定方案</Col>
  341. <Col span={20}>{theData.fixedScheme}</Col>
  342. </Row>
  343. {this.props.data.orderId ? <div>
  344. <p>状态流转记录: </p>
  345. <Table style={{ margin: '10px 0', background: "#eee" }}
  346. pagination={false}
  347. dataSource={this.state.dataSource}
  348. columns={this.state.columns} />
  349. </div> : <div></div>}
  350. {this.state.logsOrderStatus == 6 ? <div>
  351. <Button type="ghost" onClick={() => { this.handleCancel() }}>取消</Button>
  352. </div> : <div>
  353. {theData.demandOrderId ? <Button type="ghost" loading={this.state.buttonLoading}
  354. disabled={Boolean(theData.orderStatus != "0")}
  355. onClick={this.cancelSubmit}>我要撤销</Button>
  356. : <Button type="primary" onClick={() => {
  357. if (window.userData.number) {
  358. this.setState({ orderVisible: true });
  359. } else {
  360. message.warning("请先登录!");
  361. }
  362. }}>我要接单</Button>}
  363. </div>}
  364. <Modal maskClosable={false}
  365. title="我要接单"
  366. width={600}
  367. style={{ 'top': '160px' }}
  368. visible={this.state.orderVisible}
  369. footer={null}
  370. onCancel={() => { this.setState({ orderVisible: false }); }}>
  371. <Row>
  372. <Col span={2}>附件 : </Col>
  373. <Col span={8}>
  374. <Upload action={globalConfig.context + "/api/user/portal/order/demandUpload"}
  375. data={{ 'sign': 'demand_order_file' }}
  376. beforeUpload={beforeUploadFile}
  377. fileList={this.state.fileList}
  378. onChange={(info) => {
  379. if (info.file.status !== 'uploading') {
  380. console.log(info.file, info.fileList);
  381. }
  382. if (info.file.status === 'done') {
  383. if (!info.file.response.error.length) {
  384. message.success(`${info.file.name} 文件上传成功!`);
  385. } else {
  386. message.warning(info.file.response.error[0].message);
  387. return;
  388. };
  389. this.state.enclosureUrl = info.file.response.data;
  390. } else if (info.file.status === 'error') {
  391. message.error(`${info.file.name} 文件上传失败。`);
  392. };
  393. this.setState({ fileList: info.fileList.slice(-1) });
  394. }} >
  395. <Button><Icon type="upload" /> 上传相关资质附件 </Button>
  396. </Upload>
  397. </Col>
  398. </Row>
  399. <Row style={{ marginTop: '20px' }} >
  400. <Col span={2}>备注 : </Col>
  401. <Col span={22}>
  402. <Input type="textarea" rows={4} onChange={(e) => { this.state.comment = e.target.value }} />
  403. </Col>
  404. </Row>
  405. <Button loading={this.state.buttonLoading} style={{ marginTop: '20px' }} type="primary" onClick={this.handleSubmit}>提交</Button>
  406. </Modal>
  407. </Spin>
  408. </Modal>
  409. );
  410. } else {
  411. return <div></div>
  412. }
  413. },
  414. });
  415. export default DemandDetail;