intentionCustomer.jsx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  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. {
  184. title: '剩余签单天数',
  185. dataIndex: 'surplusSignTime',
  186. key: 'surplusSignTime'
  187. },{
  188. title: '客户等级',
  189. dataIndex: 'level',
  190. key: 'level',
  191. render:text => { return getLevel(text) }
  192. },
  193. {
  194. title: '跟进操作',
  195. dataIndex: 'abc',
  196. key: 'abc',
  197. render: (text, record, index) => {
  198. return <div>
  199. <Button onClick={(e) =>{ e.stopPropagation(), this.visit(record)}} type="primary">客户跟进</Button>
  200. </div>
  201. }
  202. }
  203. ],
  204. data: [],
  205. dataman: [],
  206. dataSource: [],
  207. visitArrList: [],
  208. searchTime: [, ]
  209. };
  210. },
  211. rankO(rank){
  212. let deletedIds;
  213. for(let idx = 0; idx < this.state.selectedRows.length; idx++) {
  214. let rowItem = this.state.selectedRows[idx];
  215. if(rowItem.id) {
  216. deletedIds = rowItem.id;
  217. };
  218. };
  219. $.ajax({
  220. method: "get",
  221. dataType: "json",
  222. crossDomain: false,
  223. url: globalConfig.context + "/api/admin/customer/updateUserLevel",
  224. data: {
  225. id: deletedIds, //客户的ID
  226. level:rank
  227. }
  228. }).done(function(data) {
  229. if(!data.error.length) {
  230. message.success('操作成功!');
  231. this.setState({
  232. loading: false,
  233. });
  234. } else {
  235. message.warning(data.error[0].message);
  236. };
  237. this.loadData(this.state.ispage);
  238. }.bind(this));
  239. },
  240. //进入新增拜访记录
  241. visit(e) {
  242. this.setState({
  243. followData:e,
  244. visitModul:true,
  245. modalVisible:false
  246. })
  247. },
  248. //列表删除功能
  249. delectRow() {
  250. let deletedIds;
  251. for(let idx = 0; idx < this.state.selectedRows.length; idx++) {
  252. let rowItem = this.state.selectedRows[idx];
  253. if(rowItem.id) {
  254. deletedIds = rowItem.id;
  255. };
  256. };
  257. this.setState({
  258. loading: true,
  259. selectedRowKeys: [],
  260. });
  261. $.ajax({
  262. method: "get",
  263. dataType: "json",
  264. crossDomain: false,
  265. url: globalConfig.context + "/api/admin/customer/deleteCustomer",
  266. data: {
  267. uid: deletedIds, //删除的ID
  268. }
  269. }).done(function(data) {
  270. if(!data.error.length) {
  271. message.success('删除成功!');
  272. this.setState({
  273. loading: false,
  274. });
  275. } else {
  276. message.warning(data.error[0].message);
  277. };
  278. this.loadData(this.state.ispage);
  279. }.bind(this));
  280. },
  281. componentWillMount() {
  282. //城市
  283. let Province = [];
  284. provinceList.map(function(item) {
  285. var id = String(item.id)
  286. Province.push(
  287. <Select.Option value={id} key={item.name}>{item.name}</Select.Option>
  288. )
  289. });
  290. //行业
  291. let intentionalArr = [];
  292. industry.map(function(item) {
  293. intentionalArr.push(
  294. <Select.Option value={item.value} key={item.key}>{item.key}</Select.Option>
  295. )
  296. });
  297. //会员等级
  298. let lvlArr = [];
  299. lvl.map(function(item) {
  300. lvlArr.push(
  301. <Select.Option value={item.value} key={item.key}>{item.key}</Select.Option>
  302. )
  303. });
  304. //会员状态customerStatus
  305. let currentMemberArr = [];
  306. currentMember.map(function(item) {
  307. currentMemberArr.push(
  308. <Select.Option value={item.value} key={item.key}>{item.key}</Select.Option>
  309. )
  310. });
  311. this.state.Provinces = Province;
  312. this.state.intentionalOption = intentionalArr;
  313. this.state.lvlArrOption = lvlArr;
  314. this.state.currentMemberArrOption = currentMemberArr;
  315. this.loadData();
  316. this.category()
  317. },
  318. addClick() {
  319. this.state.RowData = {};
  320. this.setState({
  321. detailApi:this.props.detailApi,
  322. showDesc: true,
  323. modalVisible:false,
  324. visitModul:false
  325. });
  326. },
  327. closeDesc(e, s) {
  328. this.state.basicState=e
  329. this.state.visitModul=e;
  330. this.state.modalVisible=e;
  331. this.state.showDesc = e;
  332. if(s) {
  333. this.loadData(this.state.ispage);
  334. };
  335. },
  336. search() {
  337. this.loadData();
  338. },
  339. reset() {
  340. this.state.nameSearch = '';
  341. this.state.level = undefined;
  342. this.state.addressSearch = [];
  343. this.state.provinceSearch = undefined;
  344. this.state.citySearch = undefined;
  345. this.state.releaseDate[0] = undefined;
  346. this.state.releaseDate[1] = undefined;
  347. this.loadData();
  348. },
  349. searchSwitch() {
  350. this.setState({
  351. visitModul:false,
  352. searchMore: !this.state.searchMore
  353. });
  354. },
  355. //整行点击
  356. tableRowClick(record, index) {
  357. this.state.visitModul=false;
  358. this.state.RowData = record;
  359. this.setState({
  360. selectedRowKeys: [],
  361. modalVisible:true,
  362. basicState:true,
  363. contactState:true,
  364. })
  365. },
  366. //指定转交人自动补全
  367. supervisor(e){
  368. $.ajax({
  369. method: "get",
  370. dataType: "json",
  371. crossDomain: false,
  372. url: globalConfig.context + "/api/admin/customer/listAdminByName",
  373. data:{
  374. adminName:e
  375. },
  376. success: function (data) {
  377. let thedata=data.data;
  378. if (!thedata) {
  379. if (data.error && data.error.length) {
  380. message.warning(data.error[0].message);
  381. };
  382. thedata = {};
  383. };
  384. this.setState({
  385. customerArr:thedata,
  386. });
  387. }.bind(this),
  388. }).always(function () {
  389. this.setState({
  390. loading: false
  391. });
  392. }.bind(this));
  393. },
  394. //上级主管输入框失去焦点是判断客户是否存在
  395. selectAuto(value,options){
  396. this.setState({
  397. auto:value
  398. })
  399. },
  400. blurChange(e){
  401. let theType='';
  402. let contactLists=this.state.customerArr||[];
  403. if (e) {
  404. contactLists.map(function (item) {
  405. if (item.name == e.toString()) {
  406. theType = item.id;
  407. }
  408. });
  409. }
  410. this.setState({
  411. theTypes:theType
  412. })
  413. },
  414. //值改变时请求客户名称
  415. httpChange(e){
  416. if(e.length>=1){
  417. this.supervisor(e);
  418. }
  419. this.setState({
  420. auto:e
  421. })
  422. },
  423. //转交
  424. changeAssigner() {
  425. if(this.state.theTypes){
  426. this.setState({
  427. selectedRowKeys: [],
  428. });
  429. let changeIds,oldAid;
  430. for(let idx = 0; idx < this.state.selectedRows.length; idx++) {
  431. let rowItem = this.state.selectedRows[idx];
  432. if(rowItem.id) {
  433. oldAid=rowItem.aid;
  434. changeIds = rowItem.id;
  435. };
  436. };
  437. $.ajax({
  438. method: "get",
  439. dataType: "json",
  440. crossDomain: false,
  441. url: globalConfig.context + "/api/admin/customer/transferToOther",
  442. data: {
  443. uid: changeIds, //这一行数据的ID
  444. aid: this.state.theTypes, //指定转交人的ID
  445. oldAid:oldAid
  446. }
  447. }).done(function(data) {
  448. if(!data.error.length) {
  449. message.success('转交成功!');
  450. this.setState({
  451. auto:'',
  452. loading: false,
  453. });
  454. } else {
  455. message.warning(data.error[0].message);
  456. };
  457. this.loadData(this.state.ispage);
  458. }.bind(this));
  459. }else{
  460. message.warning('请输入转交人姓名')
  461. }
  462. },
  463. componentWillReceiveProps(nextProps) {
  464. if(nextProps.ApiUrl!=this.props.ApiUrl) {
  465. if(!this.state.searchMore){
  466. this.state.searchMore=true
  467. }
  468. this.state.nameSearch = '';
  469. this.state.addressSearch = [];
  470. this.state.provinceSearch = undefined;
  471. this.state.citySearch = undefined;
  472. this.state.releaseDate[0] = undefined;
  473. this.state.releaseDate[1] = undefined;
  474. this.loadData(null,nextProps.ApiUrl);
  475. };
  476. },
  477. render() {
  478. const FormItem = Form.Item;
  479. const rowSelection = {
  480. selectedRowKeys: this.state.selectedRowKeys,
  481. onChange: (selectedRowKeys, selectedRows) => {
  482. this.setState({
  483. modalVisible:false,
  484. selectedRows: selectedRows.slice(-1),
  485. selectedRowKeys: selectedRowKeys.slice(-1)
  486. });
  487. },
  488. onSelect: (recordt, selected, selectedRows) => {
  489. this.setState({
  490. modalVisible:false,
  491. recordt: recordt.id
  492. })
  493. },
  494. };
  495. const hasSelected = this.state.selectedRowKeys.length > 0;
  496. const { RangePicker } = DatePicker;
  497. const dataSources=this.state.customerArr || [];
  498. const options = dataSources.map((group) =>
  499. <Select.Option key={group.id} value={group.name}>{group.name}</Select.Option>
  500. )
  501. const intentionState = this.props.intentionState ||'';
  502. return(
  503. <div className="user-content" >
  504. <div className="content-title">
  505. <span>{!intentionState?'私有单位客户':'私有专家客户'}</span>
  506. </div>
  507. <div className="user-search">
  508. <Input placeholder="客户名称"
  509. value={this.state.nameSearch}
  510. onChange={(e) => { this.setState({ nameSearch: e.target.value }); }} />
  511. <Select placeholder="省"
  512. style={{ width: 80 }}
  513. value={this.state.provinceSearch}
  514. onChange={(e) => {this.setState({ provinceSearch: e});}}>
  515. {this.state.Provinces}
  516. </Select>
  517. <span style={{marginRight:'10px'}}>
  518. <Cascader options={citySelect()} value={this.state.addressSearch} placeholder="选择城市"
  519. onChange={(e,pre) => { this.setState({ addressSearch: e }) }} />
  520. </span>
  521. <Select
  522. style={{ width: 120 }}
  523. value={this.state.level}
  524. onChange={(e) => {
  525. this.setState({ level: e });
  526. }}
  527. placeholder="请选择客户等级"
  528. >
  529. <Select.Option value="0">一般客户</Select.Option>
  530. <Select.Option value="1">意向客户</Select.Option>
  531. <Select.Option value="2">重点客户</Select.Option>
  532. </Select>
  533. <RangePicker
  534. value={[this.state.releaseDate[0] ? moment(this.state.releaseDate[0]) : null,
  535. this.state.releaseDate[1] ? moment(this.state.releaseDate[1]) : null]}
  536. onChange={(data, dataString) => { this.setState({ releaseDate: dataString }); }} />
  537. <Button type="primary" style={{marginLeft:"10px"}} onClick={this.search}>搜索</Button>
  538. <Button onClick={this.reset}>重置</Button>
  539. {/*<Button onClick={() => { window.open(globalConfig.context + '/api/admin/customer/downloadTemplate?type=1') }}>下载批量导入模板</Button>
  540. <Upload
  541. name="file"
  542. action={globalConfig.context + "/api/admin/customer/uploadExcel"}
  543. beforeUpload={beforeUploadFile}
  544. showUploadList={false}
  545. onChange={(info) => {
  546. if (info.file.status !== 'uploading') {
  547. console.log(info.file, info.fileList);
  548. }
  549. if (info.file.status === 'done') {
  550. if (!info.file.response.error.length) {
  551. message.success(`${info.file.name} 文件上传成功!`);
  552. this.loadData();
  553. } else {
  554. message.warning(info.file.response.error[0].message);
  555. return;
  556. };
  557. } else if (info.file.status === 'error') {
  558. message.error(`${info.file.name} 文件上传失败。`);
  559. };
  560. }} >
  561. <Button>上传批量内容</Button>
  562. </Upload>
  563. */}
  564. {adminData.isSuperAdmin?<Popconfirm title="是否删除?" onConfirm={this.delectRow} okText="是" cancelText="否">
  565. <Button type="danger" style={{marginLeft:'10px'}}
  566. disabled={!hasSelected}
  567. >删除<Icon type="minus" />
  568. </Button>
  569. </Popconfirm>:''
  570. }
  571. <AutoComplete
  572. className="certain-category-search"
  573. dropdownClassName="certain-category-search-dropdown"
  574. dropdownMatchSelectWidth={false}
  575. dropdownStyle={{ width: 120 }}
  576. style={{ width: '120px'}}
  577. dataSource={options}
  578. placeholder="输入转交人姓名"
  579. value={this.state.auto}
  580. onChange={this.httpChange}
  581. filterOption={true}
  582. onBlur={this.blurChange}
  583. onSelect={this.selectAuto}
  584. disabled={!hasSelected}
  585. >
  586. <Input />
  587. </AutoComplete>
  588. <Button type="primary" onClick={this.changeAssigner} disabled={!hasSelected} >转交</Button>
  589. <Button type="primary" className="addButton" onClick={this.addClick}>新增客户<Icon type="plus" /></Button>
  590. <div className='clearfix' style={{marginTop:'5px'}}>
  591. <Button onClick={(e) =>{ e.stopPropagation(), this.rankO(0)}} type="primary" style={{marginRight:"10px"}} disabled={!hasSelected}>一般客户</Button>
  592. <Button onClick={(e) =>{ e.stopPropagation(), this.rankO(1)}} type="primary" style={{marginRight:"10px"}} disabled={!hasSelected}>意向客户</Button>
  593. <Button onClick={(e) =>{ e.stopPropagation(), this.rankO(2)}} type="primary" disabled={!hasSelected}>重点客户</Button>
  594. </div>
  595. </div>
  596. <div className="patent-table">
  597. <Spin spinning={this.state.loading}>
  598. <Table columns={this.state.columns}
  599. dataSource={this.state.dataSource}
  600. rowSelection={rowSelection}
  601. pagination={this.state.pagination}
  602. onRowClick={this.tableRowClick}
  603. />
  604. </Spin>
  605. </div>
  606. <AddIntention
  607. api={this.state.detailApi}
  608. showDesc={this.state.showDesc}
  609. closeDesc={this.closeDesc}
  610. />
  611. <FollowDetail
  612. categoryArr={this.state.categoryArr}
  613. followData={this.state.followData}
  614. visitModul={this.state.visitModul}
  615. closeDesc={this.closeDesc}
  616. />
  617. <IntentionDetail
  618. categoryArr={this.state.categoryArr}
  619. detailApi={this.props.detailApi}
  620. IntentionData={this.state.RowData}
  621. modalVisible={this.state.modalVisible}
  622. closeDesc={this.closeDesc}
  623. basicState={this.state.basicState}
  624. contactState={this.state.contactState}
  625. />
  626. </div >
  627. );
  628. }
  629. }));
  630. export default IntentionCustomer;