index.jsx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. import React,{Component} from "react";
  2. import {
  3. Button,
  4. DatePicker,
  5. Form,
  6. Input,
  7. message,
  8. Select,
  9. Spin,
  10. Table,
  11. Tabs,
  12. Tooltip
  13. } from "antd";
  14. import moment from "moment";
  15. import ShowModalDiv from "@/showModal.jsx";
  16. import {ShowModal,getContactType} from "@/tools.js";
  17. import {ChooseList} from "../../../order/orderNew/chooseList";
  18. import $ from "jquery/src/ajax";
  19. import IntentionDetail from "../../NEW/intentionCustomer/intentionDetail/intentionDetail";
  20. import { getProvince } from '@/NewDicProvinceList';
  21. const {TabPane} = Tabs;
  22. const { RangePicker } = DatePicker;
  23. class FollowUpSummary extends Component{
  24. constructor(props) {
  25. super(props);
  26. this.state={
  27. loading:false,
  28. changeList:[],
  29. columns:[
  30. {
  31. title: "客户名称",
  32. dataIndex: "nickname",
  33. key: "nickname",
  34. render: text => {
  35. return (
  36. <Tooltip title={text}>
  37. <div style={{
  38. maxWidth:'150px',
  39. overflow:'hidden',
  40. textOverflow: "ellipsis",
  41. whiteSpace:'nowrap',
  42. }}>{text}</div>
  43. </Tooltip>
  44. )
  45. }
  46. },
  47. {
  48. title: '客户类型',
  49. dataIndex: 'shareType',
  50. key: 'shareType',
  51. render: text => {
  52. // 0-私有 1-公共 2 签单 3渠道
  53. return (
  54. text === 0 ? '私有客户' :
  55. text === 1 ? '公共客户' :
  56. text === 2 ? '签单客户' :
  57. text === 3 ? '渠道客户' : ''
  58. )
  59. }
  60. },
  61. {
  62. title: '客户初始时间',
  63. dataIndex: 'startTimes',
  64. key: 'startTimes',
  65. },
  66. {
  67. title: "跟进方式",
  68. dataIndex: "contactType",
  69. key: "contactType",
  70. render: (text) => {
  71. return getContactType(text);
  72. },
  73. },
  74. {
  75. title: "跟进人",
  76. dataIndex: "followName",
  77. key: "followName",
  78. },
  79. {
  80. title: "跟进部门",
  81. dataIndex: "followDep",
  82. key: "followDep",
  83. },
  84. {
  85. title: "跟进说明",
  86. dataIndex: "result",
  87. key: "result",
  88. width: 150,
  89. render: (text, record) => {
  90. return (
  91. <Tooltip placement="topLeft" title={<div style={{wordBreak:"break-all"}}>{text}</div>}>
  92. <div style={{
  93. cursor:"pointer",
  94. width: '150px',
  95. whiteSpace: 'nowrap',
  96. overflow: 'hidden',
  97. textOverflow: 'ellipsis',
  98. }}>
  99. {text}
  100. </div>
  101. </Tooltip>
  102. );
  103. },
  104. },
  105. {
  106. title: "跟进时间",
  107. dataIndex: "followTimes",
  108. key: "followTimes",
  109. },
  110. {
  111. title: "次数",
  112. dataIndex: "followCount",
  113. key: "followCount",
  114. },
  115. {
  116. title: "指导意见",
  117. dataIndex: "guidance",
  118. key: "guidance",
  119. width:150,
  120. render: (text, record) => {
  121. return (
  122. <Tooltip placement="topLeft" title={<div style={{wordBreak:"break-all"}}>{(record.guidanceName ? '('+record.guidanceName+')' : '') + text}</div>}>
  123. <div style={{
  124. cursor:"pointer",
  125. width: '150px',
  126. whiteSpace: 'nowrap',
  127. overflow: 'hidden',
  128. textOverflow: 'ellipsis',
  129. }}>
  130. {record.guidanceName ? '('+record.guidanceName+')' : null}
  131. {text}
  132. </div>
  133. </Tooltip>
  134. );
  135. },
  136. },
  137. {
  138. title: "指导时间",
  139. dataIndex: "guidanceTimes",
  140. key: "guidanceTimes",
  141. render: (text) => {
  142. return (
  143. <span>{text ? text : ''}</span>
  144. )
  145. }
  146. }
  147. ],
  148. dataSource:[],
  149. pagination: {
  150. defaultCurrent: 1,
  151. defaultPageSize: 10,
  152. showQuickJumper: true,
  153. pageSize: 10,
  154. onChange: function (page) {
  155. this.loadData(page);
  156. }.bind(this),
  157. showTotal: function (total) {
  158. return "共" + total + "条数据";
  159. },
  160. },
  161. releaseDate:[],
  162. releaseDate1:[],
  163. releaseDate2:[],
  164. userName:undefined,
  165. followName:undefined,
  166. userType:undefined,
  167. contactType:undefined,
  168. depId: undefined,
  169. shiroType: props.shiroType,
  170. }
  171. this.reset = this.reset.bind(this);
  172. this.loadData = this.loadData.bind(this);
  173. this.selectSuperId = this.selectSuperId.bind(this);
  174. this.category = this.category.bind(this);
  175. this.closeDesc = this.closeDesc.bind(this);
  176. this.tableRowClick = this.tableRowClick.bind(this);
  177. this.export = this.export.bind(this);
  178. }
  179. componentWillReceiveProps(prevProps) {
  180. if(prevProps.shiroType !== this.state.shiroType){
  181. this.setState({
  182. shiroType:prevProps.shiroType
  183. },()=>{
  184. this.reset();
  185. this.selectSuperId();
  186. })
  187. }
  188. }
  189. componentDidMount() {
  190. this.loadData();
  191. this.selectSuperId();
  192. }
  193. loadData(pageNo) {
  194. this.setState({
  195. loading: true,
  196. });
  197. let api = '/api/admin/userFollowList';
  198. $.ajax({
  199. method: "get",
  200. dataType: "json",
  201. crossDomain: false,
  202. url: globalConfig.context + api,
  203. data: {
  204. pageNo: pageNo || 1,
  205. pageSize: this.state.pagination.pageSize,
  206. userName:this.state.userName || undefined,
  207. followName: this.state.followName || undefined,
  208. userType:isNaN(parseInt(this.state.userType)) ? undefined : this.state.userType,
  209. contactType: isNaN(parseInt(this.state.contactType)) ? undefined : this.state.contactType,
  210. depId: this.state.depId || undefined,
  211. followStartTime:this.state.releaseDate[0] ? this.state.releaseDate[0] : undefined,
  212. followEndTime:this.state.releaseDate[1] ? this.state.releaseDate[1] : undefined,
  213. createStartTime:this.state.releaseDate1[0] ? this.state.releaseDate1[0] : undefined,
  214. createEndTime:this.state.releaseDate1[1] ? this.state.releaseDate1[1] : undefined,
  215. guidanceStartTime:this.state.releaseDate2[0] ? this.state.releaseDate2[0] : undefined,
  216. guidanceEndTime:this.state.releaseDate2[1] ? this.state.releaseDate2[1] : undefined,
  217. shiroType:this.state.shiroType
  218. },
  219. success: function (data) {
  220. ShowModal(this);
  221. if (data.error.length === 0) {
  222. let theArr = [];
  223. for (let i = 0; i < data.data.list.length; i++) {
  224. let thisdata = data.data.list[i];
  225. let diqu =getProvince(thisdata.province,thisdata.city,thisdata.area)
  226. thisdata.key = i;
  227. thisdata.lastFollowTime = thisdata.lastFollowTime && thisdata.lastFollowTime.split(" ")[0];
  228. thisdata.transferTime= thisdata.transferTime && thisdata.transferTime.split(" ")[0];
  229. thisdata.surplusFollowTime= thisdata.surplusFollowTime && thisdata.surplusFollowTime.split(" ")[0];
  230. thisdata.surplusSignTime= thisdata.surplusSignTime && thisdata.surplusSignTime.split(" ")[0];
  231. thisdata.locationProvince= diqu;
  232. thisdata.uid = thisdata.id;
  233. theArr.push(thisdata);
  234. }
  235. this.state.pagination.current = data.data.pageNo;
  236. this.state.pagination.total = data.data.totalCount;
  237. this.setState({
  238. pageNo: data.data.pageNo,
  239. dataSource: theArr,
  240. pagination: this.state.pagination,
  241. });
  242. }else{
  243. message.warning(data.error[0].message);
  244. }
  245. }.bind(this),
  246. }).always(
  247. function () {
  248. this.setState({
  249. loading: false,
  250. });
  251. }.bind(this)
  252. );
  253. };
  254. selectSuperId() {
  255. this.state.data = []
  256. $.ajax({
  257. method: "get",
  258. dataType: "json",
  259. crossDomain: false,
  260. url: globalConfig.context + "/api/admin/organization/selectSuperId",
  261. data:{},
  262. success: function (data) {
  263. if(data.error.length === 0){
  264. let theArr = [];
  265. for(let i=0;i<data.data.length;i++){
  266. let theData = data.data[i];
  267. theArr.push(
  268. <Select.Option value={theData.name} key={theData.name}>{theData.name}</Select.Option>
  269. );
  270. }
  271. this.setState({
  272. contactsOption: theArr,
  273. });
  274. }else{
  275. message.warning(data.error[0].message);
  276. }
  277. }.bind(this),
  278. }).always(function () {}.bind(this));
  279. }
  280. //品类数据获取
  281. category() {
  282. $.ajax({
  283. method: "get",
  284. dataType: "json",
  285. crossDomain: false,
  286. url: globalConfig.context + "/api/admin/Varieties/getSuperList",
  287. data: {},
  288. success: function (data) {
  289. let thedata = data.data;
  290. let theArr = [];
  291. if (!thedata) {
  292. if (data.error && data.error.length) {
  293. message.warning(data.error[0].message);
  294. }
  295. } else {
  296. thedata.map(function (item, index) {
  297. theArr.push({
  298. value: item.id,
  299. key: item.cname,
  300. });
  301. });
  302. }
  303. this.setState({
  304. categoryArr: theArr,
  305. });
  306. }.bind(this),
  307. });
  308. }
  309. tableRowClick(record){
  310. this.category();
  311. this.setState({
  312. rowData: record,
  313. modalVisible:true,
  314. modalName: record.nickname,
  315. })
  316. }
  317. closeDesc(e, s) {
  318. this.setState({
  319. visitModul: e,
  320. modalVisible: e,
  321. showDesc: e,
  322. tabsKey: '',
  323. })
  324. if (s) {
  325. this.loadData(this.state.pageNo);
  326. }
  327. }
  328. export(){
  329. this.setState({
  330. exportExecLoading: true
  331. })
  332. let loading = message.loading('加载中...');
  333. let data = {
  334. userName:this.state.userName || undefined,
  335. followName:this.state.followName || undefined,
  336. userType:isNaN(parseInt(this.state.userType)) ? undefined : this.state.userType,
  337. contactType: isNaN(parseInt(this.state.contactType)) ? undefined : this.state.contactType,
  338. depId:this.state.depId || undefined,
  339. followStartTime:this.state.releaseDate[0] ? this.state.releaseDate[0] : undefined,
  340. followEndTime:this.state.releaseDate[1] ? this.state.releaseDate[1] : undefined,
  341. createStartTime:this.state.releaseDate1[0] ? this.state.releaseDate1[0] : undefined,
  342. createEndTime:this.state.releaseDate1[1] ? this.state.releaseDate1[1] : undefined,
  343. guidanceStartTime:this.state.releaseDate2[0] ? this.state.releaseDate2[0] : undefined,
  344. guidanceEndTime:this.state.releaseDate2[1] ? this.state.releaseDate2[1] : undefined,
  345. shiroType:this.state.shiroType
  346. };
  347. for (let i in data){
  348. if(typeof data[i] === "undefined"){
  349. delete data[i]
  350. }
  351. }
  352. $.ajax({
  353. method: "get",
  354. dataType: "json",
  355. crossDomain: false,
  356. url: globalConfig.context + "/api/admin/userFollowListExport",
  357. data,
  358. success: function(data) {
  359. if(data.error.length === 0){
  360. this.download(data.data);
  361. }else{
  362. message.warning(data.error[0].message);
  363. }
  364. }.bind(this),
  365. }).always(function() {
  366. loading();
  367. this.setState({
  368. exportExecLoading: false
  369. })
  370. }.bind(this));
  371. }
  372. download(fileName){
  373. window.location.href = globalConfig.context + "/open/download?fileName=" + fileName
  374. }
  375. reset(){
  376. this.setState({
  377. userName:undefined,
  378. followName:undefined,
  379. userType:undefined,
  380. contactType:undefined,
  381. depId:undefined,
  382. releaseDate:[],
  383. releaseDate1:[],
  384. releaseDate2:[],
  385. },()=>{
  386. this.loadData();
  387. })
  388. }
  389. render() {
  390. return (
  391. <div className="user-content">
  392. <ShowModalDiv ShowModal={this.state.showModal} />
  393. <div className="content-title">
  394. <span>客户跟进汇总</span>
  395. </div>
  396. <Tabs defaultActiveKey="1" className="test">
  397. <TabPane tab="搜索" key="1">
  398. <div className="user-search">
  399. <Form layout="inline">
  400. <Form.Item style={{marginTop: '10px'}}>
  401. <Input
  402. placeholder="客户名称"
  403. value={this.state.userName}
  404. style={{ width: 150, marginRight: 10 }}
  405. onChange={(e) => {
  406. this.setState({ userName: e.target.value });
  407. }}
  408. />
  409. </Form.Item>
  410. <Form.Item style={{marginTop: '10px'}}>
  411. <Input
  412. placeholder="跟进人名称"
  413. value={this.state.followName}
  414. style={{ width: 150, marginRight: 10 }}
  415. onChange={(e) => {
  416. this.setState({ followName: e.target.value });
  417. }}
  418. />
  419. </Form.Item>
  420. <Form.Item>
  421. <Select
  422. placeholder="选择客户类型"
  423. style={{ width: 100, marginRight: 10}}
  424. value={this.state.userType}
  425. onChange={
  426. (e) => {
  427. this.setState({ userType: e })
  428. }}
  429. >
  430. {/*0所有 1私有客户2 公共客户 3签单客户4渠道客户*/}
  431. <Select.Option value={0}>所有</Select.Option>
  432. <Select.Option value={1}>私有客户</Select.Option>
  433. <Select.Option value={2}>公共客户</Select.Option>
  434. <Select.Option value={3}>签单客户</Select.Option>
  435. <Select.Option value={4}>渠道客户</Select.Option>
  436. </Select>
  437. </Form.Item>
  438. <Form.Item>
  439. <Select
  440. placeholder="选择跟进方式"
  441. style={{ width: 100, marginRight: 10}}
  442. value={this.state.contactType}
  443. onChange={(e) => { this.setState({ contactType: e }) }}
  444. >
  445. <Select.Option value={0}>外出</Select.Option>
  446. <Select.Option value={1}>电话</Select.Option>
  447. <Select.Option value={2}>QQ</Select.Option>
  448. <Select.Option value={3}>微信</Select.Option>
  449. <Select.Option value={4}>邮箱</Select.Option>
  450. <Select.Option value={5}>公出打卡</Select.Option>
  451. </Select>
  452. </Form.Item>
  453. <Form.Item>
  454. <Select
  455. placeholder="选择跟进部门"
  456. style={{ width:'200px',marginRight:'10px' }}
  457. value={this.state.depId}
  458. onChange={
  459. (e) => {
  460. this.setState({ depId: e })
  461. }}
  462. notFoundContent="未获取到上级组织列表"
  463. >
  464. {this.state.contactsOption}
  465. </Select>
  466. </Form.Item>
  467. <Form.Item label='跟进时间:' style={{marginTop: '10px'}}>
  468. <RangePicker
  469. style={{ marginRight:'10px' }}
  470. value={[
  471. this.state.releaseDate[0]
  472. ? moment(this.state.releaseDate[0])
  473. : null,
  474. this.state.releaseDate[1]
  475. ? moment(this.state.releaseDate[1])
  476. : null,
  477. ]}
  478. onChange={(data, dataString) => {
  479. this.setState({ releaseDate: dataString });
  480. }}
  481. />
  482. </Form.Item>
  483. <Form.Item label='客户初始时间:' style={{marginTop: '10px'}}>
  484. <RangePicker
  485. style={{ marginRight:'10px' }}
  486. value={[
  487. this.state.releaseDate1[0]
  488. ? moment(this.state.releaseDate1[0])
  489. : null,
  490. this.state.releaseDate1[1]
  491. ? moment(this.state.releaseDate1[1])
  492. : null,
  493. ]}
  494. onChange={(data, dataString) => {
  495. this.setState({ releaseDate1: dataString });
  496. }}
  497. />
  498. </Form.Item>
  499. <Form.Item label='指导时间:' style={{marginTop: '10px'}}>
  500. <RangePicker
  501. style={{ marginRight:'10px' }}
  502. value={[
  503. this.state.releaseDate2[0]
  504. ? moment(this.state.releaseDate2[0])
  505. : null,
  506. this.state.releaseDate2[1]
  507. ? moment(this.state.releaseDate2[1])
  508. : null,
  509. ]}
  510. onChange={(data, dataString) => {
  511. this.setState({ releaseDate2: dataString });
  512. }}
  513. />
  514. </Form.Item>
  515. </Form>
  516. <Button
  517. type="primary"
  518. style={{ marginLeft: "10px", marginRight: 10 }}
  519. onClick={()=>{
  520. this.loadData();
  521. }}
  522. >
  523. 搜索
  524. </Button>
  525. <Button onClick={this.reset}>重置</Button>
  526. </div>
  527. </TabPane>
  528. <TabPane tab="更改表格显示数据" key="2">
  529. <div style={{ marginLeft: 10 }}>
  530. <ChooseList
  531. columns={this.state.columns}
  532. changeFn={this.changeList}
  533. changeList={this.state.changeList}
  534. top={55}
  535. margin={11}
  536. />
  537. </div>
  538. </TabPane>
  539. <TabPane tab="导出" key="3">
  540. <Button style={{ float: "left",margin:10 }} onClick={this.export}>
  541. 导出excel
  542. </Button>
  543. </TabPane>
  544. </Tabs>
  545. <div className="patent-table">
  546. <Spin spinning={this.state.loading}>
  547. <Table
  548. columns={
  549. this.state.changeList.length
  550. ? this.state.changeList
  551. : this.state.columns
  552. }
  553. dataSource={this.state.dataSource}
  554. pagination={this.state.pagination}
  555. onRowClick={this.tableRowClick}
  556. style={{
  557. cursor: 'pointer',
  558. }}
  559. />
  560. </Spin>
  561. </div>
  562. <IntentionDetail
  563. isCustomerAdmin={this.props.isCustomerAdmin}
  564. categoryArr={this.state.categoryArr}
  565. IntentionData={this.state.rowData}
  566. modalVisible={this.state.modalVisible}
  567. isGuidanceLv={this.props.isGuidanceLv}
  568. isEditGuidanceLv={this.props.isEditGuidanceLv}
  569. name={this.state.modalName}
  570. closeDesc={this.closeDesc}
  571. />
  572. </div>
  573. )
  574. }
  575. }
  576. export default FollowUpSummary;