addIntention.jsx 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. import React from 'react';
  2. import {Modal, message, Spin, Input, Select, Button, Form, Col, Cascader, Tag, Tooltip,AutoComplete,Icon} from 'antd';
  3. import $ from 'jquery/src/ajax';
  4. import {areaSelect} from '@/NewDicProvinceList';
  5. import {socialAttribute,customerSource} from '@/dataDic.js';
  6. import TextArea from "antd/es/input/TextArea";
  7. const confirm = Modal.confirm;
  8. const AchievementDetailForm = Form.create()(React.createClass({
  9. getInitialState() {
  10. return {
  11. loading: false,
  12. data: {},
  13. detailApi:'',
  14. businessScope:[],
  15. inputVisible:false,
  16. cooperationProjects:[],
  17. selectCooperationProjects:[]
  18. };
  19. },
  20. handleSubmit(e) {
  21. // if (/.*[\u4e00-\u9fa5]+.*$/.test(this.state.content)) {
  22. // } else {
  23. // message.error("请填写正确的姓名,且至少包含一个汉字");
  24. // return;
  25. // }
  26. e.preventDefault();
  27. this.props.form.validateFields((err, values) => {
  28. if(values.name.length>64){
  29. message.warning('公司名称字数不超过64个')
  30. return false;
  31. };
  32. let regu = /[`~!#$%^&*'_[\]+=<>?:"{}|~!#¥%……&*=-@-!{}|/《》?:“”【】、;;‘’,,.。、\s+]/g;
  33. if(regu.test(values.name)){
  34. message.warning('公司名称不能存在特殊符号!')
  35. return false;
  36. }
  37. if (/.*[\u4e00-\u9fa5]+.*$/.test(values.content)) {
  38. } else {
  39. message.error("请填写正确的联系人,且至少包含一个汉字");
  40. return false;
  41. };
  42. if (/.*[\u4e00-\u9fa5]+.*$/.test(values.position)) {
  43. } else {
  44. message.error("请填写正确的职位,且至少包含一个汉字");
  45. return false;
  46. };
  47. if(!values.ProvinceCity[1]) {
  48. message.warning('请选择地区');
  49. return false;
  50. };
  51. if(values.content.length>32){
  52. message.warning('联系人字数不超过32个')
  53. return false;
  54. };
  55. if(values.length>13){
  56. message.warning('电话号码字数不超过13个')
  57. return false;
  58. };
  59. if(this.state.businessScope.length === 0){
  60. message.warning('请选择主营产品')
  61. return false;
  62. }
  63. if(this.state.selectCooperationProjects.length === 0){
  64. message.warning('请选择意向合作项目')
  65. return false;
  66. }
  67. let arr = [];
  68. for(let i of this.state.selectCooperationProjects){
  69. arr.push(i.label)
  70. }
  71. if (!err) {
  72. this.setState({
  73. loading: true
  74. });
  75. $.ajax({
  76. method: "POST",
  77. dataType: "json",
  78. crossDomain: false,
  79. url: globalConfig.context + '/api/admin/customer/addCustomer',
  80. data: {
  81. name: values.name,
  82. contacts:values.content,
  83. contactMobile:values.telnum,
  84. societyTag:'0', //社会属性默认为 社会企业
  85. //source:values.customerSource,
  86. province:(values.ProvinceCity)[0],//省
  87. city:(values.ProvinceCity)[1],//市
  88. area:(values.ProvinceCity)[2],//区
  89. type:'1',
  90. intendedProject:arr.join(','),
  91. businessScope:this.state.businessScope.join(','),
  92. position:values.position,
  93. }
  94. }).done(function (data) {
  95. this.setState({
  96. loading: false
  97. });
  98. if (!data.error.length) {
  99. message.success('保存成功!');
  100. this.setState({
  101. verification:false
  102. })
  103. this.props.handleOk();
  104. } else {
  105. message.warning(data.error[0].message);
  106. }
  107. }.bind(this));
  108. }
  109. });
  110. },
  111. componentWillMount() {
  112. this.state.name='';
  113. this.state.content='';
  114. this.state.position='';
  115. this.state.telnum='';
  116. // this.state.societyTagt='0';
  117. this.state.customerSource='0';
  118. this.state.inputValue='';
  119. this.state.businessScope = [];
  120. this.state.inputVisible = false;
  121. this.state.cooperationProjects = [];
  122. this.state.selectCooperationProjects = [];
  123. },
  124. componentWillReceiveProps(nextProps) {
  125. if (!this.props.visible && nextProps.visible) {
  126. this.state.name='';
  127. this.state.content='';
  128. this.state.position = '';
  129. this.state.telnum='';
  130. this.state.inputValue='';
  131. this.state.businessScope = [];
  132. this.state.inputVisible = false;
  133. this.state.cooperationProjects = [];
  134. this.state.selectCooperationProjects = [];
  135. // this.state.societyTagt='0';
  136. this.props.form.resetFields();
  137. };
  138. },
  139. handleClose(removedTag){
  140. let businessScope = this.state.businessScope.filter(tag => {return tag !== removedTag});
  141. this.setState({ businessScope });
  142. },
  143. handleCloseCooperation(removedTag){
  144. let selectCooperationProjects = this.state.selectCooperationProjects.filter(tag => {return tag.value !== removedTag.value});
  145. this.setState({ selectCooperationProjects });
  146. },
  147. showInput(){
  148. let str = this.state.businessScope.join('/')
  149. this.setState({
  150. inputVisible: true,
  151. inputValue: str
  152. });
  153. },
  154. handleInputConfirm(){
  155. let inputValue = this.state.inputValue;
  156. let arr = inputValue.split('/');
  157. let lv = true;
  158. for(let i of arr){
  159. if(i.length > 16){
  160. message.warning('单个标签字数不能超过16个字符')
  161. lv = false;
  162. return;
  163. }
  164. }
  165. if(lv){
  166. arr = Array.from(new Set(arr));
  167. arr = arr.filter(v=>v);
  168. this.setState({
  169. businessScope:arr,
  170. inputVisible: false,
  171. inputValue: '',
  172. });
  173. }
  174. },
  175. //加载(自动补全)
  176. supervisor(value) {
  177. $.ajax({
  178. method: "get",
  179. dataType: "json",
  180. crossDomain: false,
  181. url: globalConfig.context + '/api/admin/order/getBusinessProjectByName',
  182. data: {
  183. businessName: value
  184. },
  185. success: function (data) {
  186. let thedata = data.data;
  187. if (data.error.length === 0) {
  188. this.setState({
  189. cooperationProjects: thedata,
  190. });
  191. }else{
  192. message.warning(data.error[0].message);
  193. }
  194. }.bind(this),
  195. }).always(
  196. function () {
  197. }.bind(this)
  198. );
  199. },
  200. onSelect(value){
  201. let arr = this.state.cooperationProjects.filter(v=>v.id === value);
  202. let arr1 = this.state.selectCooperationProjects.filter(v=>v.value === value);
  203. if(arr.length > 0){
  204. if(arr1.length > 0){
  205. message.warning('选项已存在');
  206. }else{
  207. this.state.selectCooperationProjects.push({
  208. label: arr[0].bname,
  209. value: arr[0].id,
  210. })
  211. this.setState({
  212. selectCooperationProjects:this.state.selectCooperationProjects
  213. })
  214. }
  215. }
  216. },
  217. checkUserName(){
  218. this.setState({
  219. verification:false
  220. })
  221. if(!this.props.form.getFieldValue('name')){
  222. message.warning('请输入公司名称');
  223. return;
  224. }
  225. $.ajax({
  226. method: "get",
  227. dataType: "json",
  228. crossDomain: false,
  229. url: globalConfig.context + '/api/admin/customer/checkUserName',
  230. data: {
  231. userName:this.props.form.getFieldValue('name')
  232. },
  233. success: function (data) {
  234. if (data.error.length === 0) {
  235. if (!data.data) {
  236. this.setState({
  237. verification:true
  238. })
  239. } else {
  240. Modal.info({
  241. title: '提醒',
  242. content: (
  243. <div>
  244. <p>企业客户已存在!请在“客户管理-企业客户-企业客户查询”输入企业全称查询所属人信息</p>
  245. </div>
  246. ),
  247. });
  248. this.setState({
  249. verification:false
  250. })
  251. }
  252. }else{
  253. message.warning(data.error[0].message);
  254. }
  255. }.bind(this),
  256. }).always(
  257. function () {
  258. }.bind(this)
  259. );
  260. },
  261. render() {
  262. const theData = this.state.data || {};
  263. const { getFieldDecorator } = this.props.form;
  264. const FormItem = Form.Item
  265. const formItemLayout = {
  266. labelCol: { span: 6 },
  267. wrapperCol: { span: 14 },
  268. };
  269. return (
  270. <div>
  271. <Form layout="horizontal" onSubmit={this.handleSubmit} id="demand-form">
  272. <Spin spinning={this.state.loading}>
  273. <div>
  274. <Col style={{color:'red',marginBottom:'10px'}} span={12} offset={6}>注意:请录入真实有效的客户信息</Col>
  275. <div className="clearfix">
  276. <FormItem className="mid-item"
  277. {...formItemLayout}
  278. label="公司名称" >
  279. {getFieldDecorator('name', {
  280. rules: [{ required: true, message: '此项为必填项!' }],
  281. initialValue: this.state.name
  282. })(
  283. <span style={{display:'flex',alignItems:'center',position: 'relative'}}>
  284. <Input placeholder="公司名称" />
  285. {this.state.verification && <Icon type="check-circle" style={{
  286. fontSize: 16,
  287. color: '#30e031',
  288. position: 'absolute',
  289. right: '80px',
  290. }}/>}
  291. <Button onClick={this.checkUserName} type="primary" style={{marginLeft:'10px'}}>验证</Button>
  292. </span>
  293. )}
  294. </FormItem>
  295. </div>
  296. <div className="clearfix">
  297. <FormItem
  298. {...formItemLayout}
  299. label="省-市-区"
  300. >
  301. {getFieldDecorator('ProvinceCity', {
  302. rules: [{ required: true, message: '此项为必填项!' }],
  303. initialValue: this.state.ProvinceCity
  304. })(
  305. <Cascader options={areaSelect()} placeholder="选择城市" />
  306. )}
  307. </FormItem>
  308. </div>
  309. <div className="clearfix">
  310. <FormItem className="mid-item"
  311. {...formItemLayout}
  312. label="联系人" >
  313. {getFieldDecorator('content', {
  314. rules: [{ required: true, message: '此项为必填项!' }],
  315. initialValue: this.state.content
  316. })(
  317. <Input placeholder="联系人姓名" />
  318. )}
  319. </FormItem>
  320. </div>
  321. <div className="clearfix">
  322. <FormItem className="mid-item"
  323. {...formItemLayout}
  324. label="职位" >
  325. {getFieldDecorator('position', {
  326. rules: [{ required: true, message: '此项为必填项!' }],
  327. initialValue: this.state.position
  328. })(
  329. <Input placeholder="联系人职位" />
  330. )}
  331. </FormItem>
  332. </div>
  333. <div className="clearfix">
  334. <FormItem className="mid-item"
  335. {...formItemLayout}
  336. label="联系电话" >
  337. {getFieldDecorator('telnum', {
  338. rules: [{ required: true, message: '此项为必填项!' }],
  339. initialValue: this.state.telnum
  340. })(
  341. <Input placeholder="请填写手机号,仅填座机号时,请后续补充手机号" />
  342. )}
  343. </FormItem>
  344. </div>
  345. <div className="clearfix">
  346. <FormItem className="mid-item"
  347. {...formItemLayout}
  348. required
  349. label="主营产品" >
  350. <div>
  351. {this.state.businessScope.map((tag, index) => {
  352. const isLongTag = tag.length > 20;
  353. const tagElem = (
  354. <Tag closable key={tag} afterClose={() => this.handleClose(tag)}>
  355. {isLongTag ? `${tag.slice(0, 20)}...` : tag}
  356. </Tag>
  357. );
  358. return isLongTag ? <Tooltip title={tag} key={tag}>{tagElem}</Tooltip> : tagElem;
  359. })}
  360. {
  361. !this.state.inputVisible &&
  362. <Button
  363. size="small"
  364. type="primary"
  365. onClick={this.showInput}>
  366. + 新增主营产品
  367. </Button>
  368. }
  369. </div>
  370. {this.state.inputVisible && (<div>
  371. <TextArea
  372. style={{width:'300px',height:'100px'}}
  373. value={this.state.inputValue}
  374. onChange={(e)=>{
  375. this.setState({
  376. inputValue: e.target.value
  377. })
  378. }}/>
  379. <div style={{color:'#f00'}}>提示:请用 / 符号隔开关键字</div>
  380. <div>
  381. <Button
  382. size="small"
  383. type="primary"
  384. onClick={this.handleInputConfirm}>
  385. 确定
  386. </Button>
  387. <Button
  388. size="small"
  389. style={{marginLeft:'5px'}}
  390. onClick={()=>{
  391. this.setState({
  392. inputVisible: false,
  393. inputValue: ''
  394. })
  395. }}>
  396. 取消
  397. </Button>
  398. </div>
  399. </div>)}
  400. </FormItem>
  401. </div>
  402. <div className="clearfix">
  403. <FormItem
  404. className="mid-item"
  405. {...formItemLayout}
  406. required
  407. label="意向合作项目" >
  408. <div>
  409. <div style={{paddingBottom: this.state.selectCooperationProjects.length === 0 ? 0 : '10px'}}>
  410. {this.state.selectCooperationProjects.map((tag, index) => {
  411. const isLongTag = tag.label.length > 20;
  412. const tagElem = (
  413. <Tag closable key={tag.label} afterClose={() => this.handleCloseCooperation(tag)}>
  414. {isLongTag ? `${tag.label.slice(0, 20)}...` : tag.label}
  415. </Tag>
  416. );
  417. return isLongTag ? <Tooltip title={tag.label} key={tag.label}>{tagElem}</Tooltip> : tagElem;
  418. })}
  419. </div>
  420. <div>
  421. <AutoComplete
  422. style={{ width: 200 }}
  423. onSearch={this.supervisor}
  424. onSelect={this.onSelect}
  425. placeholder="请输入关键字"
  426. >
  427. {
  428. this.state.cooperationProjects.map(function (item) {
  429. return <Select.Option key={item.id} value={item.id}>{item.bname}</Select.Option>
  430. })
  431. }
  432. </AutoComplete>
  433. </div>
  434. </div>
  435. </FormItem>
  436. </div>
  437. {/*<div className="clearfix">*/}
  438. {/* <FormItem className="mid-item"*/}
  439. {/* {...formItemLayout}*/}
  440. {/* label="社会属性"*/}
  441. {/* >*/}
  442. {/* {getFieldDecorator('societyTagt', {*/}
  443. {/* rules: [{ required: true, message: '此项为必填项!' }],*/}
  444. {/* initialValue: this.state.societyTagt*/}
  445. {/* })(*/}
  446. {/* <Select placeholder="客户社会属性">*/}
  447. {/* {*/}
  448. {/* socialAttribute.map(function (item) {*/}
  449. {/* return <Select.Option key={item.value} >{item.key}</Select.Option>*/}
  450. {/* })*/}
  451. {/* }*/}
  452. {/* </Select>*/}
  453. {/* )}*/}
  454. {/* </FormItem>*/}
  455. {/*</div>*/}
  456. </div>
  457. <FormItem wrapperCol={{ span: 12, offset: 6 }}>
  458. <Button type="primary" htmlType="submit" style={{marginRight:'50px'}}>保存</Button>
  459. <Button type="ghost" onClick={this.props.closeDesc}>取消</Button>
  460. </FormItem>
  461. </Spin>
  462. </Form >
  463. </div>
  464. )
  465. }
  466. }));
  467. const AddPerson = Form.create()(React.createClass({
  468. getInitialState() {
  469. return {
  470. loading: false,
  471. data: {},
  472. detailApi:''
  473. };
  474. },
  475. handleSubmit(e) {
  476. e.preventDefault();
  477. this.props.form.validateFields((err, values) => {
  478. if(values.companyNamet.length>64){
  479. message.warning('联系人字数不超过64个')
  480. return false;
  481. };
  482. if(!values.ProvinceCity[1]) {
  483. message.warning('请选择地区');
  484. return false;
  485. };
  486. if(values.telnums.length>13){
  487. message.warning('电话号码字数不超过13个')
  488. return false;
  489. };
  490. if (!err) {
  491. this.setState({
  492. loading: true
  493. });
  494. $.ajax({
  495. method: "POST",
  496. dataType: "json",
  497. crossDomain: false,
  498. url: globalConfig.context + '/api/admin/customer/addCustomer',
  499. data: {
  500. contacts:values.companyNamet,
  501. societyTag:values.societyTagt,
  502. name: values.companyNamet,
  503. contactMobile: values.telnums,
  504. source:values.customerSource,
  505. province:(values.ProvinceCity)[0],//省
  506. city:(values.ProvinceCity)[1],//市
  507. area:(values.ProvinceCity)[2],//区
  508. type:'0'
  509. }
  510. }).done(function (data) {
  511. this.setState({
  512. loading: false
  513. });
  514. if (!data.error.length) {
  515. message.success('保存成功!');
  516. this.props.handleOk();
  517. } else {
  518. message.warning(data.error[0].message);
  519. }
  520. }.bind(this));
  521. }
  522. });
  523. },
  524. componentWillMount() {
  525. this.state.companyNamet='';
  526. this.state.telnum='';
  527. this.state.societyTagt='0';
  528. this.state.customerSource='0';
  529. },
  530. componentWillReceiveProps(nextProps) {
  531. if (!this.props.visible && nextProps.visible) {
  532. this.state.companyNamet='';
  533. this.state.telnum='';
  534. this.state.societyTagt='0';
  535. this.state.customerSource='0';
  536. this.props.form.resetFields();
  537. };
  538. },
  539. render() {
  540. const theData = this.state.data || {};
  541. const { getFieldDecorator } = this.props.form;
  542. const FormItem = Form.Item
  543. const formItemLayout = {
  544. labelCol: { span: 6 },
  545. wrapperCol: { span: 14 },
  546. };
  547. return (
  548. <div>
  549. <Form layout="horizontal" onSubmit={this.handleSubmit} id="demand-form">
  550. <Spin spinning={this.state.loading}>
  551. <Col style={{color:'red',marginBottom:'10px'}} span={12} offset={6}>注意:请录入真实有效的客户信息</Col>
  552. <div className="clearfix">
  553. <FormItem className="mid-item"
  554. {...formItemLayout}
  555. label="客户姓名" >
  556. {getFieldDecorator('companyNamet', {
  557. rules: [{ required: true, message: '此项为必填项!' }],
  558. initialValue: this.state.companyNamet
  559. })(
  560. <Input placeholder="客户姓名" />
  561. )}
  562. </FormItem>
  563. </div>
  564. <div className="clearfix">
  565. <FormItem
  566. {...formItemLayout}
  567. label="省-市-区"
  568. >
  569. {getFieldDecorator('ProvinceCity', {
  570. rules: [{ required: true, message: '此项为必填项!' }],
  571. initialValue: this.state.ProvinceCity
  572. })(
  573. <Cascader options={areaSelect()} placeholder="选择城市" />
  574. )}
  575. </FormItem>
  576. </div>
  577. <div className="clearfix">
  578. <FormItem className="mid-item"
  579. {...formItemLayout}
  580. label="联系电话" >
  581. {getFieldDecorator('telnums', {
  582. rules: [{ required: true, message: '此项为必填项!' }],
  583. initialValue: this.state.telnums
  584. })(
  585. <Input placeholder="联系电话" />
  586. )}
  587. </FormItem>
  588. </div>
  589. <div className="clearfix">
  590. <FormItem className="mid-item"
  591. {...formItemLayout}
  592. label="社会属性"
  593. >
  594. {getFieldDecorator('societyTagt', {
  595. rules: [{ required: true, message: '此项为必填项!' }],
  596. initialValue: this.state.societyTagt
  597. })(
  598. <Select placeholder="客户社会属性">
  599. {
  600. socialAttribute.map(function (item) {
  601. return <Select.Option key={item.value} >{item.key}</Select.Option>
  602. })
  603. }
  604. </Select>
  605. )}
  606. </FormItem>
  607. </div>
  608. <div className="clearfix">
  609. <FormItem className="mid-item"
  610. {...formItemLayout}
  611. label="客户来源"
  612. >
  613. {getFieldDecorator('customerSource', {
  614. rules: [{ required: true, message: '此项为必填项!' }],
  615. initialValue: this.state.customerSource
  616. })(
  617. <Select placeholder="客户来源">
  618. {
  619. customerSource.map(function (item) {
  620. return <Select.Option key={item.value} >{item.key}</Select.Option>
  621. })
  622. }
  623. </Select>
  624. )}
  625. </FormItem>
  626. </div>
  627. <FormItem wrapperCol={{ span: 12, offset: 6 }}>
  628. <Button style={{marginRight:'50px'}} type="primary" htmlType="submit">保存</Button>
  629. <Button type="ghost" onClick={this.props.closeDesc}>取消</Button>
  630. </FormItem>
  631. </Spin>
  632. </Form >
  633. </div>
  634. )
  635. }
  636. }));
  637. const AddIntention = React.createClass({
  638. getInitialState() {
  639. return {
  640. visible: false,
  641. tabsKey: 1,
  642. loading: false,
  643. dataSource: [],
  644. };
  645. },
  646. handleCancel(e) {
  647. this.setState({
  648. visible: false,
  649. });
  650. this.props.closeDesc(false);
  651. },
  652. handleOk(e) {
  653. this.setState({
  654. visible: false,
  655. });
  656. this.props.closeDesc(false, true);
  657. },
  658. componentWillReceiveProps(nextProps) {
  659. if (!this.state.visible && nextProps.showDesc) {
  660. this.state.tabsKey = "1";
  661. };
  662. this.state.visible = nextProps.showDesc;
  663. },
  664. render() {
  665. return (
  666. <div className="patent-desc">
  667. <Modal maskClosable={false} visible={this.state.visible}
  668. onOk={this.checkPatentProcess} onCancel={this.handleCancel}
  669. width='600px'
  670. title='新建客户'
  671. footer=''
  672. className="admin-desc-content">
  673. <Spin spinning={this.state.loading}>
  674. {this.props.api.indexOf('Personal')<0?<AchievementDetailForm
  675. data={this.props.data}
  676. newmodal={this.props.newmodal}
  677. closeDesc={this.handleCancel}
  678. visible={this.state.visible}
  679. handleOk={this.handleOk} />:<AddPerson
  680. data={this.props.data}
  681. newmodal={this.props.newmodal}
  682. closeDesc={this.handleCancel}
  683. visible={this.state.visible}
  684. handleOk={this.handleOk}
  685. />}
  686. </Spin>
  687. </Modal>
  688. </div>
  689. );
  690. },
  691. });
  692. export default Form.create({})(AddIntention);