index.jsx 27 KB

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