intentionCustomer.jsx 18 KB

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