techProduct.jsx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. import React from 'react';
  2. import { Icon, Form, Button, Radio, Input, Spin, Table, message, Select, Modal, DatePicker, Cascader, Transfer, InputNumber } from 'antd';
  3. import { techFieldList, technicalSourceList } from '../../dataDic.js';
  4. import { getTechField, getTechnicalSource } from '../../tools.js';
  5. import './techProduct.less';
  6. import moment from 'moment';
  7. import ajax from 'jquery/src/ajax/xhr.js';
  8. import $ from 'jquery/src/ajax';
  9. const TechProductDescFrom = Form.create()(React.createClass({
  10. getInitialState() {
  11. return {
  12. loading: false,
  13. targetKeys: [],
  14. selectedKeys: [],
  15. technicalSourceOption: [],
  16. };
  17. },
  18. componentWillMount() {
  19. let _me = this;
  20. technicalSourceList.map(function (item) {
  21. _me.state.technicalSourceOption.push(
  22. <Select.Option value={item.value} key={10000 + item.value}>{item.key}</Select.Option>
  23. )
  24. });
  25. this.state.targetKeys = this.props.data.intellectualPropertyNumber;
  26. },
  27. componentWillReceiveProps(nextProps) {
  28. if (nextProps.data) {
  29. this.state.targetKeys = nextProps.data.intellectualPropertyNumber;
  30. };
  31. },
  32. handleSubmit(e) {
  33. e.preventDefault();
  34. this.props.form.validateFields((err, values) => {
  35. if (!err) {
  36. this.props.spinState(true);
  37. $.ajax({
  38. method: "POST",
  39. dataType: "json",
  40. crossDomain: false,
  41. url: globalConfig.context + "/techservice/cognizance/techProduct",
  42. data: {
  43. id: this.props.data.id,
  44. serialNumber: values.serialNumber,
  45. productName: values.productName,
  46. technicalField1: values.techField[0],
  47. technicalField2: values.techField[1],
  48. technicalField3: values.techField[2],
  49. technicalSource: values.technicalSource,
  50. lastYearRevenue: values.lastYearRevenue,
  51. mainProduct: values.mainProduct,
  52. intellectualPropertyNumber: this.state.targetKeys.join(","),
  53. keyTechnology: values.keyTechnology,
  54. competitiveEdge: values.competitiveEdge,
  55. conditionEffect: values.conditionEffect
  56. }
  57. }).done(function (data) {
  58. if (!data.error.length) {
  59. message.success('保存成功!');
  60. this.props.closeModal();
  61. this.props.form.resetFields();
  62. this.state.targetKeys = [];
  63. this.state.selectedKeys = [];
  64. } else {
  65. message.warning(data.error[0].message);
  66. this.props.spinState(false);
  67. }
  68. }.bind(this));
  69. }
  70. });
  71. },
  72. intellectualChange(nextTargetKeys, direction, moveKeys) {
  73. this.setState({ targetKeys: nextTargetKeys });
  74. },
  75. intellectualSelectChange(sourceSelectedKeys, targetSelectedKeys) {
  76. this.setState({ selectedKeys: [...sourceSelectedKeys, ...targetSelectedKeys] });
  77. },
  78. render() {
  79. const FormItem = Form.Item;
  80. const { getFieldDecorator } = this.props.form;
  81. const theData = this.props.data;
  82. const formItemLayout = {
  83. labelCol: { span: 10 },
  84. wrapperCol: { span: 12 },
  85. };
  86. const _me = this;
  87. return (
  88. <Form onSubmit={this.handleSubmit} className="activityCost-form">
  89. <div className="clearfix">
  90. <FormItem className="half-item"
  91. {...formItemLayout}
  92. label="编号:ps"
  93. >
  94. {getFieldDecorator('serialNumber', {
  95. rules: [{ required: true, message: '此项为必填项!' }],
  96. initialValue: theData.serialNumber
  97. })(
  98. <Input />
  99. )}
  100. </FormItem>
  101. <FormItem className="half-item"
  102. {...formItemLayout}
  103. label="产品(服务)名称"
  104. >
  105. {getFieldDecorator('productName', {
  106. rules: [{ required: true, message: '此项为必填项!' }],
  107. initialValue: theData.productName
  108. })(
  109. <Input />
  110. )}
  111. </FormItem>
  112. </div>
  113. <div className="clearfix">
  114. <FormItem className="half-item"
  115. {...formItemLayout}
  116. label="技术来源"
  117. >
  118. {getFieldDecorator('technicalSource', {
  119. rules: [{ required: true, message: '此项为必填项!' }],
  120. initialValue: theData.technicalSource
  121. })(
  122. <Select placeholder="选择技术来源"
  123. onChange={(e) => { this.setState({ technicalSource: e }) }}>
  124. {this.state.technicalSourceOption}
  125. </Select>
  126. )}
  127. </FormItem>
  128. <FormItem className="half-item"
  129. labelCol={{ span: 10 }}
  130. label="上年度销售收入(万元)"
  131. >
  132. {getFieldDecorator('lastYearRevenue', {
  133. rules: [{ type: "number", required: true, message: '此项为必填项!' }],
  134. initialValue: theData.lastYearRevenue ? Number(theData.lastYearRevenue) : 0
  135. })(
  136. <InputNumber />
  137. )}
  138. </FormItem>
  139. </div>
  140. <FormItem
  141. labelCol={{ span: 5 }}
  142. wrapperCol={{ span: 16 }}
  143. label="技术领域"
  144. >
  145. {getFieldDecorator('techField', {
  146. rules: [{ type: "array", required: true, message: '此项为必填项!' }],
  147. initialValue: theData.techField
  148. })(
  149. <Cascader
  150. options={techFieldList}
  151. onChange={(value, selectedOptions) => { this.setState({ techField: value }); console.log(value) }}
  152. placeholder="请选择"
  153. showSearch
  154. />
  155. )}
  156. </FormItem>
  157. <div className="clearfix">
  158. <FormItem className="half-item"
  159. {...formItemLayout}
  160. label="是否主要产品(服务)"
  161. >
  162. {getFieldDecorator('mainProduct', {
  163. rules: [{ type: "number", required: true, message: '此项为必填项!' }],
  164. initialValue: theData.mainProduct
  165. })(
  166. <Radio.Group>
  167. <Radio value={1}>是</Radio>
  168. <Radio value={0}>否</Radio>
  169. </Radio.Group>
  170. )}
  171. </FormItem>
  172. </div>
  173. <p>知识产权编号:</p>
  174. <Transfer
  175. dataSource={this.props.mockData}
  176. listStyle={{
  177. width: 200,
  178. height: 200,
  179. }}
  180. titles={['未选择', '已选择']}
  181. targetKeys={this.state.targetKeys}
  182. selectedKeys={this.state.selectedKeys}
  183. onChange={this.intellectualChange}
  184. onSelectChange={this.intellectualSelectChange}
  185. render={item => `${item.name}-${item.key}`}
  186. />
  187. <div className="clearfix">
  188. <FormItem className="half-item"
  189. labelCol={{ span: 0 }}
  190. wrapperCol={{ span: 22 }}
  191. >
  192. <p>关键技术及主要技术指标(限400字)</p>
  193. {getFieldDecorator('keyTechnology', {
  194. rules: [{ required: true, message: '此项为必填项!' }],
  195. initialValue: theData.keyTechnology
  196. })(
  197. <Input type='textarea' rows={6} onChange={(e) => { if (e.target.value.length > 400) { return; } }} />
  198. )}
  199. </FormItem>
  200. <FormItem className="half-item"
  201. labelCol={{ span: 0 }}
  202. wrapperCol={{ span: 22 }}
  203. >
  204. <p>与同类产品(服务)的竞争优势(限400字)</p>
  205. {getFieldDecorator('competitiveEdge', {
  206. rules: [{ required: true, message: '此项为必填项!' }],
  207. initialValue: theData.competitiveEdge
  208. })(
  209. <Input type='textarea' rows={6} onChange={(e) => { if (e.target.value.length > 400) { return; } }} />
  210. )}
  211. </FormItem>
  212. <p style={{ lineHeight: "32px" }}>知识产权获得情况及其对产品(服务)在技术上发挥的支持作用(限400字)*</p>
  213. <FormItem className="half-item"
  214. labelCol={{ span: 0 }}
  215. wrapperCol={{ span: 22 }}
  216. >
  217. {getFieldDecorator('conditionEffect', {
  218. rules: [{ required: true, message: '此项为必填项!' }],
  219. initialValue: theData.conditionEffect
  220. })(
  221. <Input type='textarea' rows={6} onChange={(e) => { if (e.target.value.length > 400) { return; } }} />
  222. )}
  223. </FormItem>
  224. </div>
  225. <FormItem style={{ marginTop: '20px' }}>
  226. <Button className="set-submit" type="primary" htmlType="submit">保存</Button>
  227. <Button type="ghost" style={{ marginLeft: '20px' }} onClick={this.props.closeModal}>取消</Button>
  228. </FormItem>
  229. </Form >
  230. );
  231. },
  232. }));
  233. const TechProductDesc = React.createClass({
  234. getInitialState() {
  235. return {
  236. visible: false,
  237. loading: false
  238. };
  239. },
  240. componentWillReceiveProps(nextProps) {
  241. this.state.visible = nextProps.showDesc
  242. },
  243. showModal() {
  244. this.setState({
  245. visible: true,
  246. });
  247. },
  248. handleOk() {
  249. this.setState({
  250. visible: false,
  251. });
  252. this.props.closeDesc(false);
  253. },
  254. handleCancel(e) {
  255. this.setState({
  256. visible: false,
  257. });
  258. this.props.closeDesc(false);
  259. },
  260. spinChange(e) {
  261. this.setState({
  262. loading: e
  263. });
  264. },
  265. render() {
  266. return (
  267. <div className="patent-addNew">
  268. <Spin spinning={this.state.loading} className='spin-box'>
  269. <Modal title="上年度高新技术产品(服务)情况表" visible={this.state.visible}
  270. onOk={this.handleOk} onCancel={this.handleCancel}
  271. width='800px'
  272. footer=''
  273. >
  274. <TechProductDescFrom data={this.props.data} mockData={this.props.mockData}
  275. spinState={this.spinChange} closeModal={this.handleCancel} />
  276. </Modal>
  277. </Spin>
  278. </div>
  279. );
  280. },
  281. });
  282. const TechProduct = React.createClass({
  283. loadData(pageNo) {
  284. this.state.data = [];
  285. this.setState({
  286. loading: true
  287. });
  288. $.when($.ajax({
  289. method: "get",
  290. dataType: "json",
  291. crossDomain: false,
  292. url: globalConfig.context + "/techservice/cognizance/techProductList",
  293. data: {
  294. pageNo: pageNo || 1,
  295. pageSize: this.state.pagination.pageSize
  296. }
  297. }), $.ajax({
  298. method: "get",
  299. dataType: "json",
  300. crossDomain: false,
  301. url: globalConfig.context + "/techservice/cognizance/intellectualList",
  302. data: {
  303. pageNo: pageNo || 1,
  304. pageSize: 99,
  305. }
  306. })).done((data1, data2) => {
  307. let data = data1[0];
  308. let intellectualList = data2[0];
  309. if (data.error.length || !data.data || !data.data.list) {
  310. message.warning(data.error[0].message);
  311. return;
  312. };
  313. if (intellectualList.error.length || !intellectualList.data || !intellectualList.data.list) {
  314. message.warning(intellectualList.error[0].message);
  315. return;
  316. };
  317. let theArr = [];
  318. for (let i = 0; i < intellectualList.data.list.length; i++) {
  319. theArr.push({
  320. key: intellectualList.data.list[i].intellectualPropertyNumber,
  321. name: intellectualList.data.list[i].intellectualPropertyName
  322. });
  323. };
  324. this.state.mockData = theArr;
  325. for (let i = 0; i < data.data.list.length; i++) {
  326. let thisdata = data.data.list[i];
  327. this.state.data.push({
  328. key: i,
  329. id: thisdata.id,
  330. uid: thisdata.uid,
  331. mockData: this.state.mockData,
  332. serialNumber: thisdata.serialNumber,
  333. productName: thisdata.productName,
  334. techField: [Number(thisdata.technicalField1), Number(thisdata.technicalField2), Number(thisdata.technicalField3)],
  335. technicalField: getTechField(thisdata.technicalField1, thisdata.technicalField2, thisdata.technicalField3),
  336. technicalField1: thisdata.technicalField1,
  337. technicalField2: thisdata.technicalField2,
  338. technicalField3: thisdata.technicalField3,
  339. technicalSource: String(thisdata.technicalSource),
  340. lastYearRevenue: thisdata.lastYearRevenue,
  341. mainProduct: thisdata.mainProduct,
  342. PropertyNumber:thisdata.intellectualPropertyNumber,
  343. intellectualPropertyNumber: thisdata.intellectualPropertyNumber ? thisdata.intellectualPropertyNumber.split(",") : [],
  344. keyTechnology: thisdata.keyTechnology,
  345. competitiveEdge: thisdata.competitiveEdge,
  346. conditionEffect: thisdata.conditionEffect,
  347. year: thisdata.year,
  348. createTime: thisdata.createTime,
  349. });
  350. };
  351. this.state.pagination.current = data.data.pageNo;
  352. this.state.pagination.total = data.data.totalCount;
  353. this.setState({
  354. dataSource: this.state.data,
  355. pagination: this.state.pagination
  356. });
  357. }).always(function () {
  358. this.setState({
  359. loading: false
  360. });
  361. }.bind(this));
  362. },
  363. getInitialState() {
  364. return {
  365. selectedRowKeys: [],
  366. selectedRows: [],
  367. loading: false,
  368. pagination: {
  369. defaultCurrent: 1,
  370. defaultPageSize: 10,
  371. showQuickJumper: true,
  372. pageSize: 10,
  373. onChange: function (page) {
  374. this.loadData(page);
  375. }.bind(this),
  376. showTotal: function (total) {
  377. return '共' + total + '条数据';
  378. }
  379. },
  380. columns: [
  381. {
  382. title: '产品编号',
  383. dataIndex: 'serialNumber',
  384. key: 'serialNumber'
  385. }, {
  386. title: '产品(服务)名称',
  387. dataIndex: 'productName',
  388. key: 'productName'
  389. }, {
  390. title: '技术领域',
  391. dataIndex: 'technicalField',
  392. key: 'technicalField'
  393. }, {
  394. title: '技术来源',
  395. dataIndex: 'technicalSource',
  396. key: 'technicalSource',
  397. render: (text) => { return getTechnicalSource(text) }
  398. }, {
  399. title: '上年度销售收入(万元)',
  400. dataIndex: 'lastYearRevenue',
  401. key: 'lastYearRevenue'
  402. }, {
  403. title: '是否主要产品(服务)',
  404. dataIndex: 'mainProduct',
  405. key: 'mainProduct',
  406. render: (text) => { if (text == "1") { return '是' } else { return '否' } }
  407. }, {
  408. title: '知识产权编号',
  409. dataIndex: 'PropertyNumber',
  410. key: 'PropertyNumber'
  411. }
  412. ],
  413. dataSource: []
  414. };
  415. },
  416. componentWillMount() {
  417. this.loadData();
  418. },
  419. tableRowClick(record, index) {
  420. this.state.RowData = record;
  421. this.setState({
  422. showDesc: true
  423. });
  424. },
  425. delectRow() {
  426. let deletedIds = [];
  427. for (let idx = 0; idx < this.state.selectedRows.length; idx++) {
  428. let rowItem = this.state.selectedRows[idx];
  429. if (rowItem.id) {
  430. deletedIds.push(rowItem.id)
  431. }
  432. }
  433. this.setState({
  434. selectedRowKeys: [],
  435. loading: deletedIds.length > 0
  436. });
  437. $.ajax({
  438. method: "POST",
  439. dataType: "json",
  440. crossDomain: false,
  441. url: globalConfig.context + "/techservice/cognizance/deleteTechProduct",
  442. data: {
  443. ids: deletedIds
  444. }
  445. }).done(function (data) {
  446. if (!data.error.length) {
  447. message.success('保存成功!');
  448. this.setState({
  449. loading: false,
  450. });
  451. } else {
  452. message.warning(data.error[0].message);
  453. };
  454. this.loadData();
  455. }.bind(this));
  456. },
  457. closeDesc(e) {
  458. this.state.showDesc = e;
  459. this.loadData();
  460. },
  461. search() {
  462. this.loadData();
  463. },
  464. reset() {
  465. this.loadData();
  466. },
  467. render() {
  468. const rowSelection = {
  469. selectedRowKeys: this.state.selectedRowKeys,
  470. onChange: (selectedRowKeys, selectedRows) => {
  471. this.setState({
  472. selectedRows: selectedRows,
  473. selectedRowKeys: selectedRowKeys
  474. });
  475. }
  476. };
  477. const hasSelected = this.state.selectedRowKeys.length > 0;
  478. return (
  479. <div className="user-content" >
  480. <div className="content-title">
  481. <span>上年度高新技术产品(服务)情况表</span>
  482. </div>
  483. <div className="user-search">
  484. <p>
  485. <Button style={{ background: "#ea0862", border: "none", color: "#fff" }}
  486. onClick={this.tableRowClick}>添加<Icon type="plus" /></Button>
  487. <Button style={{ background: "#3fcf9e", border: "none", color: "#fff" }}
  488. disabled={!hasSelected}
  489. onClick={this.delectRow}>删除<Icon type="minus" /></Button>
  490. </p>
  491. </div>
  492. <div className="patent-table">
  493. <Spin spinning={this.state.loading}>
  494. <Table columns={this.state.columns}
  495. dataSource={this.state.dataSource}
  496. pagination={this.state.pagination}
  497. rowSelection={rowSelection}
  498. onRowClick={this.tableRowClick} />
  499. </Spin>
  500. </div>
  501. <TechProductDesc data={this.state.RowData}
  502. mockData={this.state.mockData}
  503. showDesc={this.state.showDesc} closeDesc={this.closeDesc} />
  504. </div >
  505. );
  506. }
  507. });
  508. export default TechProduct;