intentionCustomer.jsx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  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. })
  327. },
  328. //指定转交人自动补全
  329. supervisor(e){
  330. $.ajax({
  331. method: "get",
  332. dataType: "json",
  333. crossDomain: false,
  334. url: globalConfig.context + "/api/admin/customer/listAdminByName",
  335. data:{
  336. adminName:e
  337. },
  338. success: function (data) {
  339. let thedata=data.data;
  340. if (!thedata) {
  341. if (data.error && data.error.length) {
  342. message.warning(data.error[0].message);
  343. };
  344. thedata = {};
  345. };
  346. this.setState({
  347. customerArr:thedata,
  348. });
  349. }.bind(this),
  350. }).always(function () {
  351. this.setState({
  352. loading: false
  353. });
  354. }.bind(this));
  355. },
  356. //上级主管输入框失去焦点是判断客户是否存在
  357. selectAuto(value,options){
  358. this.setState({
  359. auto:value
  360. })
  361. },
  362. blurChange(e){
  363. let theType='';
  364. let contactLists=this.state.customerArr||[];
  365. if (e) {
  366. contactLists.map(function (item) {
  367. if (item.name == e.toString()) {
  368. theType = item.id;
  369. }
  370. });
  371. }
  372. this.setState({
  373. theTypes:theType
  374. })
  375. },
  376. //值改变时请求客户名称
  377. httpChange(e){
  378. if(e.length>=1){
  379. this.supervisor(e);
  380. }
  381. this.setState({
  382. auto:e
  383. })
  384. },
  385. //转交
  386. changeAssigner() {
  387. if(this.state.theTypes){
  388. this.setState({
  389. selectedRowKeys: [],
  390. });
  391. let changeIds,oldAid;
  392. for(let idx = 0; idx < this.state.selectedRows.length; idx++) {
  393. let rowItem = this.state.selectedRows[idx];
  394. if(rowItem.id) {
  395. oldAid=rowItem.aid;
  396. changeIds = rowItem.id;
  397. };
  398. };
  399. $.ajax({
  400. method: "get",
  401. dataType: "json",
  402. crossDomain: false,
  403. url: globalConfig.context + "/api/admin/customer/transferToOther",
  404. data: {
  405. uid: changeIds, //这一行数据的ID
  406. aid: this.state.theTypes, //指定转交人的ID
  407. oldAid:oldAid
  408. }
  409. }).done(function(data) {
  410. if(!data.error.length) {
  411. message.success('转交成功!');
  412. this.setState({
  413. auto:'',
  414. loading: false,
  415. });
  416. } else {
  417. message.warning(data.error[0].message);
  418. };
  419. this.loadData(this.state.ispage);
  420. }.bind(this));
  421. }else{
  422. message.warning('请输入转交人姓名')
  423. }
  424. },
  425. componentWillReceiveProps(nextProps) {
  426. if(nextProps.ApiUrl!=this.props.ApiUrl) {
  427. if(!this.state.searchMore){
  428. this.state.searchMore=true
  429. }
  430. this.state.nameSearch = '';
  431. this.state.addressSearch = [];
  432. this.state.provinceSearch = undefined;
  433. this.state.citySearch = undefined;
  434. this.state.releaseDate[0] = undefined;
  435. this.state.releaseDate[1] = undefined;
  436. this.loadData(null,nextProps.ApiUrl);
  437. };
  438. },
  439. render() {
  440. const FormItem = Form.Item;
  441. const rowSelection = {
  442. selectedRowKeys: this.state.selectedRowKeys,
  443. onChange: (selectedRowKeys, selectedRows) => {
  444. this.setState({
  445. modalVisible:false,
  446. selectedRows: selectedRows.slice(-1),
  447. selectedRowKeys: selectedRowKeys.slice(-1)
  448. });
  449. },
  450. onSelect: (recordt, selected, selectedRows) => {
  451. this.setState({
  452. modalVisible:false,
  453. recordt: recordt.id
  454. })
  455. },
  456. };
  457. const hasSelected = this.state.selectedRowKeys.length > 0;
  458. const { RangePicker } = DatePicker;
  459. const dataSources=this.state.customerArr || [];
  460. const options = dataSources.map((group) =>
  461. <Select.Option key={group.id} value={group.name}>{group.name}</Select.Option>
  462. )
  463. const intentionState = this.props.intentionState ||'';
  464. return(
  465. <div className="user-content" >
  466. <div className="content-title">
  467. <span>{!intentionState?'我的单位意向客户':'我的个人意向客户'}</span>
  468. </div>
  469. <div className="user-search">
  470. <Input placeholder="客户名称"
  471. value={this.state.nameSearch}
  472. onChange={(e) => { this.setState({ nameSearch: e.target.value }); }} />
  473. <Select placeholder="省"
  474. style={{ width: 80 }}
  475. value={this.state.provinceSearch}
  476. onChange={(e) => {this.setState({ provinceSearch: e});}}>
  477. {this.state.Provinces}
  478. </Select>
  479. <span style={{marginRight:'10px'}}>
  480. <Cascader options={citySelect()} value={this.state.addressSearch} placeholder="选择城市"
  481. onChange={(e,pre) => { this.setState({ addressSearch: e }) }} />
  482. </span>
  483. <Button type="primary" onClick={this.search}>搜索</Button>
  484. <Button onClick={this.reset}>重置</Button>
  485. {/*<Button onClick={() => { window.open(globalConfig.context + '/api/admin/customer/downloadTemplate?type=1') }}>下载批量导入模板</Button>
  486. <Upload
  487. name="file"
  488. action={globalConfig.context + "/api/admin/customer/uploadExcel"}
  489. beforeUpload={beforeUploadFile}
  490. showUploadList={false}
  491. onChange={(info) => {
  492. if (info.file.status !== 'uploading') {
  493. console.log(info.file, info.fileList);
  494. }
  495. if (info.file.status === 'done') {
  496. if (!info.file.response.error.length) {
  497. message.success(`${info.file.name} 文件上传成功!`);
  498. this.loadData();
  499. } else {
  500. message.warning(info.file.response.error[0].message);
  501. return;
  502. };
  503. } else if (info.file.status === 'error') {
  504. message.error(`${info.file.name} 文件上传失败。`);
  505. };
  506. }} >
  507. <Button>上传批量内容</Button>
  508. </Upload>
  509. */}
  510. {adminData.isSuperAdmin?<Popconfirm title="是否删除?" onConfirm={this.delectRow} okText="是" cancelText="否">
  511. <Button type="danger" style={{marginLeft:'10px'}}
  512. disabled={!hasSelected}
  513. >删除<Icon type="minus" />
  514. </Button>
  515. </Popconfirm>:''
  516. }
  517. <AutoComplete
  518. className="certain-category-search"
  519. dropdownClassName="certain-category-search-dropdown"
  520. dropdownMatchSelectWidth={false}
  521. dropdownStyle={{ width: 120 }}
  522. style={{ width: '120px'}}
  523. dataSource={options}
  524. placeholder="输入转交人姓名"
  525. value={this.state.auto}
  526. onChange={this.httpChange}
  527. filterOption={true}
  528. onBlur={this.blurChange}
  529. onSelect={this.selectAuto}
  530. disabled={!hasSelected}
  531. >
  532. <Input />
  533. </AutoComplete>
  534. <Button type="primary" onClick={this.changeAssigner} disabled={!hasSelected} >转交</Button>
  535. <span style={{marginLeft:'10px',marginRight:'20px'}}>更多搜索<Switch checked={!this.state.searchMore} onChange={this.searchSwitch} /></span>
  536. <Button type="primary" className="addButton" onClick={this.addClick}>新增客户<Icon type="plus" /></Button>
  537. <div className='clearfix' style={{marginTop:'5px'}}>
  538. <div className="search-more" style={this.state.searchMore ? { display: 'none' } : {}}>
  539. <RangePicker
  540. value={[this.state.releaseDate[0] ? moment(this.state.releaseDate[0]) : null,
  541. this.state.releaseDate[1] ? moment(this.state.releaseDate[1]) : null]}
  542. onChange={(data, dataString) => { this.setState({ releaseDate: dataString }); }} />
  543. </div>
  544. </div>
  545. </div>
  546. <div className="patent-table">
  547. <Spin spinning={this.state.loading}>
  548. <Table columns={this.state.columns}
  549. dataSource={this.state.dataSource}
  550. rowSelection={rowSelection}
  551. pagination={this.state.pagination}
  552. onRowClick={this.tableRowClick}
  553. />
  554. </Spin>
  555. </div>
  556. <AddIntention
  557. api={this.state.detailApi}
  558. showDesc={this.state.showDesc}
  559. closeDesc={this.closeDesc}
  560. />
  561. <FollowDetail
  562. categoryArr={this.state.categoryArr}
  563. followData={this.state.followData}
  564. visitModul={this.state.visitModul}
  565. closeDesc={this.closeDesc}
  566. />
  567. <IntentionDetail
  568. categoryArr={this.state.categoryArr}
  569. detailApi={this.props.detailApi}
  570. IntentionData={this.state.RowData}
  571. modalVisible={this.state.modalVisible}
  572. closeDesc={this.closeDesc}
  573. basicState={this.state.basicState}
  574. />
  575. </div >
  576. );
  577. }
  578. }));
  579. export default IntentionCustomer;