intentionCustomer.jsx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. import React from 'react';
  2. import { Radio, Icon, Button, AutoComplete,Cascader,Input, Select, Spin, Popconfirm, Table, Switch, message, DatePicker, Upload, Form } from 'antd';
  3. import ajax from 'jquery/src/ajax/xhr.js';
  4. import $ from 'jquery/src/ajax';
  5. import moment from 'moment';
  6. import { citySelect, provinceList } from '@/NewDicProvinceList';
  7. import AddIntention from './addIntention.jsx';
  8. import { socialAttribute, industry, auditStatusL, lvl, currentMember } from '@/dataDic.js';
  9. import { getSocialAttribute, beforeUploadFile ,getLevel} from '@/tools.js';
  10. import FollowDetail from './followDetail.jsx'
  11. import IntentionDetail from './intentionDetail/intentionDetail.jsx'
  12. import './customer.less';
  13. const IntentionCustomer = Form.create()(React.createClass({
  14. loadData(pageNo, apiUrl) {
  15. this.setState({
  16. visitModul:false,
  17. loading: true,
  18. ispage:pageNo,
  19. modalVisible:false
  20. });
  21. let api=apiUrl?apiUrl:this.props.ApiUrl;
  22. $.ajax({
  23. method: "post",
  24. dataType: "json",
  25. crossDomain: false,
  26. url: globalConfig.context + api,
  27. data: {
  28. pageNo: pageNo || 1,
  29. pageSize: this.state.pagination.pageSize,
  30. level:this.state.level?this.state.level:undefined,
  31. name: this.state.nameSearch,
  32. province: !(this.state.addressSearch).length ? this.state.provinceSearch : this.state.addressSearch[0],
  33. city: !(this.state.addressSearch).length ? '' : this.state.addressSearch[1],
  34. startDate: this.state.releaseDate[0],
  35. endDate: this.state.releaseDate[1],
  36. },
  37. success: function(data) {
  38. let theArr = [];
  39. if(data.error.length || data.data.list == "") {
  40. if(data.error && data.error.length) {
  41. message.warning(data.error[0].message);
  42. };
  43. } else {
  44. for(let i = 0; i < data.data.list.length; i++) {
  45. let thisdata = data.data.list[i];
  46. let diqu=(thisdata.province==null?"":thisdata.province)+(thisdata.city==null?"":"-"+thisdata.city)+(thisdata.area==null?"":"-"+thisdata.area);
  47. theArr.push({
  48. key: i,
  49. id: thisdata.uid,
  50. aid:thisdata.aid,
  51. name: thisdata.name,
  52. contacts: thisdata.contacts,
  53. contactMobile: thisdata.contactMobile,
  54. industry: thisdata.industry,
  55. societyTag: thisdata.societyTag,
  56. lastFollowTime:thisdata.lastFollowTime&&thisdata.lastFollowTime.split(' ')[0],
  57. transferTime:thisdata.transferTime&&thisdata.transferTime.split(' ')[0],
  58. surplusFollowTime:thisdata.surplusFollowTime&&thisdata.surplusFollowTime.split(' ')[0],
  59. surplusSignTime:thisdata.surplusSignTime&&thisdata.surplusSignTime.split(' ')[0],
  60. locationProvince: diqu,
  61. level:thisdata.level,
  62. });
  63. };
  64. this.state.pagination.current = data.data.pageNo;
  65. this.state.pagination.total = data.data.totalCount;
  66. };
  67. if(data.data&&data.data.list&&!data.data.list.length){
  68. this.state.pagination.current=0
  69. this.state.pagination.total=0
  70. }
  71. this.setState({
  72. dataSource: theArr,
  73. pagination: this.state.pagination,
  74. selectedRowKeys:[]
  75. });
  76. }.bind(this),
  77. }).always(function() {
  78. this.setState({
  79. loading: false
  80. });
  81. }.bind(this));
  82. },
  83. //品类数据获取
  84. category(){
  85. $.ajax({
  86. method: "get",
  87. dataType: "json",
  88. crossDomain: false,
  89. url: globalConfig.context + "/api/admin/Varieties/getSuperList",
  90. data: {
  91. },
  92. success: function(data) {
  93. let thedata = data.data;
  94. let theArr=[];
  95. if(!thedata) {
  96. if(data.error && data.error.length) {
  97. message.warning(data.error[0].message);
  98. };
  99. thedata = {};
  100. }else{
  101. thedata.map(function(item,index){
  102. theArr.push({
  103. value:item.id,
  104. key:item.cname,
  105. })
  106. })
  107. }
  108. this.setState({
  109. categoryArr:theArr,
  110. })
  111. }.bind(this),
  112. });
  113. },
  114. getInitialState() {
  115. return {
  116. addressSearch: [],
  117. orgCodeUrl: [],
  118. companyLogoUrl: [],
  119. visible: false,
  120. searchMore: true,
  121. releaseDate: [],
  122. categoryArr:[],
  123. visitModul:false,
  124. keys:false,
  125. detailApi:'',
  126. followData:{},
  127. selectedRowKeys: [],
  128. selectedRowKey: [],
  129. selectedRows: [],
  130. loading: false,
  131. modalVisible:false,
  132. pagination: {
  133. defaultCurrent: 1,
  134. defaultPageSize: 10,
  135. showQuickJumper: true,
  136. pageSize: 10,
  137. onChange: function(page) {
  138. this.loadData(page);
  139. }.bind(this),
  140. showTotal: function(total) {
  141. return '共' + total + '条数据';
  142. }
  143. },
  144. columns: [{
  145. title: '客户名称',
  146. dataIndex: 'name',
  147. key: 'name',
  148. }, {
  149. title: '地区',
  150. dataIndex: 'locationProvince',
  151. key: 'locationProvince',
  152. }, {
  153. title: '联系人',
  154. dataIndex: 'contacts',
  155. key: 'contacts',
  156. },
  157. {
  158. title: '联系电话',
  159. dataIndex: 'contactMobile',
  160. key: 'contactMobile',
  161. },
  162. {
  163. title: '社会性质',
  164. dataIndex: 'societyTag',
  165. key: 'societyTag',
  166. render: text => { return getSocialAttribute(text) }
  167. },
  168. {
  169. title: '客户初始时间',
  170. dataIndex: 'transferTime',
  171. key: 'transferTime',
  172. },
  173. {
  174. title: '剩余私有天数',
  175. dataIndex: 'surplusFollowTime',
  176. key: 'surplusFollowTime'
  177. },
  178. {
  179. title: '最新跟进时间',
  180. dataIndex: 'lastFollowTime',
  181. key: 'lastFollowTime',
  182. },{
  183. title: '客户等级',
  184. dataIndex: 'level',
  185. key: 'level',
  186. render:text => { return getLevel(text) }
  187. },
  188. {
  189. title: '跟进操作',
  190. dataIndex: 'abc',
  191. key: 'abc',
  192. render: (text, record, index) => {
  193. return <div>
  194. <Button onClick={(e) =>{ e.stopPropagation(), this.visit(record)}} type="primary">客户跟进</Button>
  195. </div>
  196. }
  197. }
  198. ],
  199. data: [],
  200. dataman: [],
  201. dataSource: [],
  202. visitArrList: [],
  203. searchTime: [, ]
  204. };
  205. },
  206. rankO(rank){
  207. let deletedIds;
  208. for(let idx = 0; idx < this.state.selectedRows.length; idx++) {
  209. let rowItem = this.state.selectedRows[idx];
  210. if(rowItem.id) {
  211. deletedIds = rowItem.id;
  212. };
  213. };
  214. $.ajax({
  215. method: "get",
  216. dataType: "json",
  217. crossDomain: false,
  218. url: globalConfig.context + "/api/admin/customer/updateUserLevel",
  219. data: {
  220. id: deletedIds, //客户的ID
  221. level:rank
  222. }
  223. }).done(function(data) {
  224. if(!data.error.length) {
  225. message.success('操作成功!');
  226. this.setState({
  227. loading: false,
  228. });
  229. } else {
  230. message.warning(data.error[0].message);
  231. };
  232. this.loadData(this.state.ispage);
  233. }.bind(this));
  234. },
  235. //进入新增拜访记录
  236. visit(e) {
  237. this.setState({
  238. followData:e,
  239. visitModul:true,
  240. modalVisible:false
  241. })
  242. },
  243. //列表删除功能
  244. delectRow() {
  245. let deletedIds;
  246. for(let idx = 0; idx < this.state.selectedRows.length; idx++) {
  247. let rowItem = this.state.selectedRows[idx];
  248. if(rowItem.id) {
  249. deletedIds = rowItem.id;
  250. };
  251. };
  252. this.setState({
  253. loading: true,
  254. selectedRowKeys: [],
  255. });
  256. $.ajax({
  257. method: "get",
  258. dataType: "json",
  259. crossDomain: false,
  260. url: globalConfig.context + "/api/admin/customer/deleteCustomer",
  261. data: {
  262. uid: deletedIds, //删除的ID
  263. }
  264. }).done(function(data) {
  265. if(!data.error.length) {
  266. message.success('删除成功!');
  267. this.setState({
  268. loading: false,
  269. });
  270. } else {
  271. message.warning(data.error[0].message);
  272. };
  273. this.loadData(this.state.ispage);
  274. }.bind(this));
  275. },
  276. componentWillMount() {
  277. //城市
  278. let Province = [];
  279. provinceList.map(function(item) {
  280. var id = String(item.id)
  281. Province.push(
  282. <Select.Option value={id} key={item.name}>{item.name}</Select.Option>
  283. )
  284. });
  285. //行业
  286. let intentionalArr = [];
  287. industry.map(function(item) {
  288. intentionalArr.push(
  289. <Select.Option value={item.value} key={item.key}>{item.key}</Select.Option>
  290. )
  291. });
  292. //会员等级
  293. let lvlArr = [];
  294. lvl.map(function(item) {
  295. lvlArr.push(
  296. <Select.Option value={item.value} key={item.key}>{item.key}</Select.Option>
  297. )
  298. });
  299. //会员状态customerStatus
  300. let currentMemberArr = [];
  301. currentMember.map(function(item) {
  302. currentMemberArr.push(
  303. <Select.Option value={item.value} key={item.key}>{item.key}</Select.Option>
  304. )
  305. });
  306. this.state.Provinces = Province;
  307. this.state.intentionalOption = intentionalArr;
  308. this.state.lvlArrOption = lvlArr;
  309. this.state.currentMemberArrOption = currentMemberArr;
  310. this.loadData();
  311. this.category()
  312. },
  313. addClick() {
  314. this.state.RowData = {};
  315. this.setState({
  316. detailApi:this.props.detailApi,
  317. showDesc: true,
  318. modalVisible:false,
  319. visitModul:false
  320. });
  321. },
  322. closeDesc(e, s) {
  323. this.state.basicState=e
  324. this.state.visitModul=e;
  325. this.state.modalVisible=e;
  326. this.state.showDesc = e;
  327. if(s) {
  328. this.loadData(this.state.ispage);
  329. };
  330. },
  331. search() {
  332. this.loadData();
  333. },
  334. reset() {
  335. this.state.nameSearch = '';
  336. this.state.level = undefined;
  337. this.state.addressSearch = [];
  338. this.state.provinceSearch = undefined;
  339. this.state.citySearch = undefined;
  340. this.state.releaseDate[0] = undefined;
  341. this.state.releaseDate[1] = undefined;
  342. this.loadData();
  343. },
  344. searchSwitch() {
  345. this.setState({
  346. visitModul:false,
  347. searchMore: !this.state.searchMore
  348. });
  349. },
  350. //整行点击
  351. tableRowClick(record, index) {
  352. this.state.visitModul=false;
  353. this.state.RowData = record;
  354. this.setState({
  355. selectedRowKeys: [],
  356. modalVisible:true,
  357. basicState:true,
  358. contactState:true,
  359. })
  360. },
  361. //指定转交人自动补全
  362. supervisor(e){
  363. $.ajax({
  364. method: "get",
  365. dataType: "json",
  366. crossDomain: false,
  367. url: globalConfig.context + "/api/admin/customer/listAdminByName",
  368. data:{
  369. adminName:e
  370. },
  371. success: function (data) {
  372. let thedata=data.data;
  373. if (!thedata) {
  374. if (data.error && data.error.length) {
  375. message.warning(data.error[0].message);
  376. };
  377. thedata = {};
  378. };
  379. this.setState({
  380. customerArr:thedata,
  381. });
  382. }.bind(this),
  383. }).always(function () {
  384. this.setState({
  385. loading: false
  386. });
  387. }.bind(this));
  388. },
  389. //上级主管输入框失去焦点是判断客户是否存在
  390. selectAuto(value,options){
  391. this.setState({
  392. auto:value
  393. })
  394. },
  395. blurChange(e){
  396. let theType='';
  397. let contactLists=this.state.customerArr||[];
  398. if (e) {
  399. contactLists.map(function (item) {
  400. if (item.name == e.toString()) {
  401. theType = item.id;
  402. }
  403. });
  404. }
  405. this.setState({
  406. theTypes:theType
  407. })
  408. },
  409. //值改变时请求客户名称
  410. httpChange(e){
  411. if(e.length>=1){
  412. this.supervisor(e);
  413. }
  414. this.setState({
  415. auto:e
  416. })
  417. },
  418. //转交
  419. changeAssigner() {
  420. if(this.state.theTypes){
  421. this.setState({
  422. selectedRowKeys: [],
  423. });
  424. let changeIds,oldAid;
  425. for(let idx = 0; idx < this.state.selectedRows.length; idx++) {
  426. let rowItem = this.state.selectedRows[idx];
  427. if(rowItem.id) {
  428. oldAid=rowItem.aid;
  429. changeIds = rowItem.id;
  430. };
  431. };
  432. $.ajax({
  433. method: "get",
  434. dataType: "json",
  435. crossDomain: false,
  436. url: globalConfig.context + "/api/admin/customer/transferToOther",
  437. data: {
  438. uid: changeIds, //这一行数据的ID
  439. aid: this.state.theTypes, //指定转交人的ID
  440. oldAid:oldAid
  441. }
  442. }).done(function(data) {
  443. if(!data.error.length) {
  444. message.success('转交成功!');
  445. this.setState({
  446. auto:'',
  447. loading: false,
  448. });
  449. } else {
  450. message.warning(data.error[0].message);
  451. };
  452. this.loadData(Math.min(this.state.ispage==undefined?1:this.state.ispage,Math.ceil((this.state.pagination.total-1)/10)));
  453. }.bind(this));
  454. }else{
  455. message.warning('请输入转交人姓名')
  456. }
  457. },
  458. componentWillReceiveProps(nextProps) {
  459. if(nextProps.ApiUrl!=this.props.ApiUrl) {
  460. if(!this.state.searchMore){
  461. this.state.searchMore=true
  462. }
  463. this.state.nameSearch = '';
  464. this.state.addressSearch = [];
  465. this.state.provinceSearch = undefined;
  466. this.state.citySearch = undefined;
  467. this.state.releaseDate[0] = undefined;
  468. this.state.releaseDate[1] = undefined;
  469. this.loadData(null,nextProps.ApiUrl);
  470. };
  471. },
  472. render() {
  473. const FormItem = Form.Item;
  474. const rowSelection = {
  475. selectedRowKeys: this.state.selectedRowKeys,
  476. onChange: (selectedRowKeys, selectedRows) => {
  477. this.setState({
  478. modalVisible:false,
  479. selectedRows: selectedRows.slice(-1),
  480. selectedRowKeys: selectedRowKeys.slice(-1)
  481. });
  482. },
  483. onSelect: (recordt, selected, selectedRows) => {
  484. this.setState({
  485. modalVisible:false,
  486. recordt: recordt.id
  487. })
  488. },
  489. };
  490. const hasSelected = this.state.selectedRowKeys.length > 0;
  491. const { RangePicker } = DatePicker;
  492. const dataSources=this.state.customerArr || [];
  493. const options = dataSources.map((group) =>
  494. <Select.Option key={group.id} value={group.name}>{group.name}</Select.Option>
  495. )
  496. const intentionState = this.props.intentionState ||'';
  497. return(
  498. <div className="user-content" >
  499. <div className="content-title">
  500. <span>{!intentionState?'私有单位客户':'私有专家客户'}</span>
  501. </div>
  502. <div className="user-search">
  503. <Input placeholder="客户名称"
  504. value={this.state.nameSearch}
  505. onChange={(e) => { this.setState({ nameSearch: e.target.value }); }} />
  506. <Select placeholder="省"
  507. style={{ width: 80 }}
  508. value={this.state.provinceSearch}
  509. onChange={(e) => {this.setState({ provinceSearch: e});}}>
  510. {this.state.Provinces}
  511. </Select>
  512. <span style={{marginRight:'10px'}}>
  513. <Cascader options={citySelect()} value={this.state.addressSearch} placeholder="选择城市"
  514. onChange={(e,pre) => { this.setState({ addressSearch: e }) }} />
  515. </span>
  516. <Select
  517. style={{ width: 120 }}
  518. value={this.state.level}
  519. onChange={(e) => {
  520. this.setState({ level: e });
  521. }}
  522. placeholder="请选择客户等级"
  523. >
  524. <Select.Option value="0">一般客户</Select.Option>
  525. <Select.Option value="1">意向客户</Select.Option>
  526. <Select.Option value="2">重点客户</Select.Option>
  527. </Select>
  528. <RangePicker
  529. value={[this.state.releaseDate[0] ? moment(this.state.releaseDate[0]) : null,
  530. this.state.releaseDate[1] ? moment(this.state.releaseDate[1]) : null]}
  531. onChange={(data, dataString) => { this.setState({ releaseDate: dataString }); }} />
  532. <Button type="primary" style={{marginLeft:"10px"}} onClick={this.search}>搜索</Button>
  533. <Button onClick={this.reset}>重置</Button>
  534. {/*<Button onClick={() => { window.open(globalConfig.context + '/api/admin/customer/downloadTemplate?type=1') }}>下载批量导入模板</Button>
  535. <Upload
  536. name="file"
  537. action={globalConfig.context + "/api/admin/customer/uploadExcel"}
  538. beforeUpload={beforeUploadFile}
  539. showUploadList={false}
  540. onChange={(info) => {
  541. if (info.file.status !== 'uploading') {
  542. console.log(info.file, info.fileList);
  543. }
  544. if (info.file.status === 'done') {
  545. if (!info.file.response.error.length) {
  546. message.success(`${info.file.name} 文件上传成功!`);
  547. this.loadData();
  548. } else {
  549. message.warning(info.file.response.error[0].message);
  550. return;
  551. };
  552. } else if (info.file.status === 'error') {
  553. message.error(`${info.file.name} 文件上传失败。`);
  554. };
  555. }} >
  556. <Button>上传批量内容</Button>
  557. </Upload>
  558. {adminData.isSuperAdmin?<Popconfirm title="是否删除?" onConfirm={this.delectRow} okText="是" cancelText="否">
  559. <Button type="danger" style={{marginLeft:'10px'}}
  560. disabled={!hasSelected}
  561. >删除<Icon type="minus" />
  562. </Button>
  563. </Popconfirm>:''
  564. }*/}
  565. <AutoComplete
  566. className="certain-category-search"
  567. dropdownClassName="certain-category-search-dropdown"
  568. dropdownMatchSelectWidth={false}
  569. dropdownStyle={{ width: 120 }}
  570. style={{ width: '120px'}}
  571. dataSource={options}
  572. placeholder="输入转交人姓名"
  573. value={this.state.auto}
  574. onChange={this.httpChange}
  575. filterOption={true}
  576. onBlur={this.blurChange}
  577. onSelect={this.selectAuto}
  578. disabled={!hasSelected}
  579. >
  580. <Input />
  581. </AutoComplete>
  582. <Button type="primary" onClick={this.changeAssigner} disabled={!hasSelected} >转交</Button>
  583. <Button type="primary" className="addButton" onClick={this.addClick}>新增客户<Icon type="plus" /></Button>
  584. <div className='clearfix' style={{marginTop:'5px'}}>
  585. <Button onClick={(e) =>{ e.stopPropagation(), this.rankO(0)}} type="primary" style={{marginRight:"10px"}} disabled={!hasSelected}>一般客户</Button>
  586. <Button onClick={(e) =>{ e.stopPropagation(), this.rankO(1)}} type="primary" style={{marginRight:"10px"}} disabled={!hasSelected}>意向客户</Button>
  587. <Button onClick={(e) =>{ e.stopPropagation(), this.rankO(2)}} type="primary" disabled={!hasSelected}>重点客户</Button>
  588. </div>
  589. </div>
  590. <div className="patent-table">
  591. <Spin spinning={this.state.loading}>
  592. <Table columns={this.state.columns}
  593. dataSource={this.state.dataSource}
  594. rowSelection={rowSelection}
  595. pagination={this.state.pagination}
  596. onRowClick={this.tableRowClick}
  597. />
  598. </Spin>
  599. </div>
  600. <AddIntention
  601. api={this.state.detailApi}
  602. showDesc={this.state.showDesc}
  603. closeDesc={this.closeDesc}
  604. />
  605. <FollowDetail
  606. categoryArr={this.state.categoryArr}
  607. followData={this.state.followData}
  608. visitModul={this.state.visitModul}
  609. closeDesc={this.closeDesc}
  610. />
  611. <IntentionDetail
  612. categoryArr={this.state.categoryArr}
  613. detailApi={this.props.detailApi}
  614. IntentionData={this.state.RowData}
  615. modalVisible={this.state.modalVisible}
  616. closeDesc={this.closeDesc}
  617. basicState={this.state.basicState}
  618. contactState={this.state.contactState}
  619. />
  620. </div >
  621. );
  622. }
  623. }));
  624. export default IntentionCustomer;