index.jsx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  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.loadData();
  192. // this.selectSuperId();
  193. }
  194. loadData(pageNo) {
  195. this.setState({
  196. loading: true,
  197. });
  198. let api = '/api/admin/userFollowList';
  199. $.ajax({
  200. method: "get",
  201. dataType: "json",
  202. crossDomain: false,
  203. url: globalConfig.context + api,
  204. data: {
  205. pageNo: pageNo || 1,
  206. pageSize: this.state.pagination.pageSize,
  207. userName: this.state.userName || undefined,
  208. followName: this.state.followName || undefined,
  209. userType: isNaN(parseInt(this.state.userType)) ? undefined : this.state.userType,
  210. contactType: isNaN(parseInt(this.state.contactType)) ? undefined : this.state.contactType,
  211. deps: this.state.deps || undefined,
  212. followStartTime: this.state.releaseDate[0] ? this.state.releaseDate[0] : undefined,
  213. followEndTime: this.state.releaseDate[1] ? this.state.releaseDate[1] : undefined,
  214. createStartTime: this.state.releaseDate1[0] ? this.state.releaseDate1[0] : undefined,
  215. createEndTime: this.state.releaseDate1[1] ? this.state.releaseDate1[1] : undefined,
  216. guidanceStartTime: this.state.releaseDate2[0] ? this.state.releaseDate2[0] : undefined,
  217. guidanceEndTime: this.state.releaseDate2[1] ? this.state.releaseDate2[1] : undefined,
  218. shiroType: this.state.shiroType
  219. },
  220. success: function (data) {
  221. ShowModal(this);
  222. if (data.error.length === 0) {
  223. let theArr = [];
  224. for (let i = 0; i < data.data.list.length; i++) {
  225. let thisdata = data.data.list[i];
  226. let diqu = getProvince(thisdata.province, thisdata.city, thisdata.area)
  227. thisdata.key = i;
  228. thisdata.lastFollowTime = thisdata.lastFollowTime && thisdata.lastFollowTime.split(" ")[0];
  229. thisdata.transferTime = thisdata.transferTime && thisdata.transferTime.split(" ")[0];
  230. thisdata.surplusFollowTime = thisdata.surplusFollowTime && thisdata.surplusFollowTime.split(" ")[0];
  231. thisdata.surplusSignTime = thisdata.surplusSignTime && thisdata.surplusSignTime.split(" ")[0];
  232. thisdata.locationProvince = diqu;
  233. thisdata.uid = thisdata.id;
  234. theArr.push(thisdata);
  235. }
  236. this.state.pagination.current = data.data.pageNo;
  237. this.state.pagination.total = data.data.totalCount;
  238. this.setState({
  239. pageNo: data.data.pageNo,
  240. dataSource: theArr,
  241. pagination: this.state.pagination,
  242. });
  243. } else {
  244. message.warning(data.error[0].message);
  245. }
  246. }.bind(this),
  247. }).always(
  248. function () {
  249. this.setState({
  250. loading: false,
  251. });
  252. }.bind(this)
  253. );
  254. };
  255. selectSuperId() {
  256. this.state.data = []
  257. $.ajax({
  258. method: "get",
  259. dataType: "json",
  260. crossDomain: false,
  261. url: globalConfig.context + "/api/admin/organization/selectSuperId",
  262. data: {},
  263. success: function (data) {
  264. if (data.error.length === 0) {
  265. let theArr = [];
  266. for (let i = 0; i < data.data.length; i++) {
  267. let theData = data.data[i];
  268. theArr.push(
  269. <Select.Option value={theData.id} key={theData.name}>{theData.name}</Select.Option>
  270. );
  271. }
  272. this.setState({
  273. contactsOption: theArr,
  274. });
  275. } else {
  276. message.warning(data.error[0].message);
  277. }
  278. }.bind(this),
  279. }).always(function () { }.bind(this));
  280. }
  281. //品类数据获取
  282. category() {
  283. $.ajax({
  284. method: "get",
  285. dataType: "json",
  286. crossDomain: false,
  287. url: globalConfig.context + "/api/admin/Varieties/getSuperList",
  288. data: {},
  289. success: function (data) {
  290. let thedata = data.data;
  291. let theArr = [];
  292. if (!thedata) {
  293. if (data.error && data.error.length) {
  294. message.warning(data.error[0].message);
  295. }
  296. } else {
  297. thedata.map(function (item, index) {
  298. theArr.push({
  299. value: item.id,
  300. key: item.cname,
  301. });
  302. });
  303. }
  304. this.setState({
  305. categoryArr: theArr,
  306. });
  307. }.bind(this),
  308. });
  309. }
  310. tableRowClick(record) {
  311. this.category();
  312. this.setState({
  313. rowData: record,
  314. modalVisible: true,
  315. modalName: record.nickname,
  316. })
  317. }
  318. closeDesc(e, s) {
  319. this.setState({
  320. visitModul: e,
  321. modalVisible: e,
  322. showDesc: e,
  323. tabsKey: '',
  324. })
  325. if (s) {
  326. this.loadData(this.state.pageNo);
  327. }
  328. }
  329. export() {
  330. this.setState({
  331. exportExecLoading: true
  332. })
  333. let loading = message.loading('加载中...');
  334. let data = {
  335. userName: this.state.userName || undefined,
  336. followName: this.state.followName || undefined,
  337. userType: isNaN(parseInt(this.state.userType)) ? undefined : this.state.userType,
  338. contactType: isNaN(parseInt(this.state.contactType)) ? undefined : this.state.contactType,
  339. deps: this.state.deps || undefined,
  340. followStartTime: this.state.releaseDate[0] ? this.state.releaseDate[0] : undefined,
  341. followEndTime: this.state.releaseDate[1] ? this.state.releaseDate[1] : undefined,
  342. createStartTime: this.state.releaseDate1[0] ? this.state.releaseDate1[0] : undefined,
  343. createEndTime: this.state.releaseDate1[1] ? this.state.releaseDate1[1] : undefined,
  344. guidanceStartTime: this.state.releaseDate2[0] ? this.state.releaseDate2[0] : undefined,
  345. guidanceEndTime: this.state.releaseDate2[1] ? this.state.releaseDate2[1] : undefined,
  346. shiroType: this.state.shiroType
  347. };
  348. for (let i in data) {
  349. if (typeof data[i] === "undefined") {
  350. delete data[i]
  351. }
  352. }
  353. $.ajax({
  354. method: "get",
  355. dataType: "json",
  356. crossDomain: false,
  357. url: globalConfig.context + "/api/admin/userFollowListExport",
  358. data,
  359. success: function (data) {
  360. if (data.error.length === 0) {
  361. this.download(data.data);
  362. } else {
  363. message.warning(data.error[0].message);
  364. }
  365. }.bind(this),
  366. }).always(function () {
  367. loading();
  368. this.setState({
  369. exportExecLoading: false
  370. })
  371. }.bind(this));
  372. }
  373. download(fileName) {
  374. window.location.href = globalConfig.context + "/open/download?fileName=" + fileName
  375. }
  376. reset() {
  377. this.setState({
  378. userName: undefined,
  379. followName: undefined,
  380. userType: undefined,
  381. contactType: undefined,
  382. deps: undefined,
  383. releaseDate: [],
  384. releaseDate1: [],
  385. releaseDate2: [],
  386. }, () => {
  387. this.Cascaders.empty();
  388. this.loadData();
  389. })
  390. }
  391. render() {
  392. return (
  393. <div className="user-content">
  394. <ShowModalDiv ShowModal={this.state.showModal} />
  395. <div className="content-title" style={{ marginBottom: 10 }}>
  396. <span style={{ fontWeight: 900, fontSize: 16 }}>客户跟进汇总</span>
  397. </div>
  398. <Tabs defaultActiveKey="1" className="test">
  399. <TabPane tab="搜索" key="1">
  400. <div className="user-search">
  401. <Form layout="inline">
  402. <Form.Item style={{ marginTop: '10px' }}>
  403. <Input
  404. placeholder="客户名称"
  405. value={this.state.userName}
  406. style={{ width: 150, marginRight: 10 }}
  407. onChange={(e) => {
  408. this.setState({ userName: e.target.value });
  409. }}
  410. />
  411. </Form.Item>
  412. <Form.Item style={{ marginTop: '10px' }}>
  413. <Input
  414. placeholder="跟进人名称"
  415. value={this.state.followName}
  416. style={{ width: 150, marginRight: 10 }}
  417. onChange={(e) => {
  418. this.setState({ followName: e.target.value });
  419. }}
  420. />
  421. </Form.Item>
  422. <Form.Item>
  423. <Select
  424. placeholder="选择客户类型"
  425. style={{ width: 100, marginRight: 10 }}
  426. value={this.state.userType}
  427. onChange={
  428. (e) => {
  429. this.setState({ userType: e })
  430. }}
  431. >
  432. {/*0所有 1私有客户2 公共客户 3签单客户4外联客户*/}
  433. <Select.Option value={0}>所有</Select.Option>
  434. <Select.Option value={1}>私有客户</Select.Option>
  435. <Select.Option value={2}>公共客户</Select.Option>
  436. <Select.Option value={3}>签单客户</Select.Option>
  437. <Select.Option value={4}>外联客户</Select.Option>
  438. </Select>
  439. </Form.Item>
  440. <Form.Item>
  441. <Select
  442. placeholder="选择跟进方式"
  443. style={{ width: 100, marginRight: 10 }}
  444. value={this.state.contactType}
  445. onChange={(e) => { this.setState({ contactType: e }) }}
  446. >
  447. <Select.Option value={0}>外出</Select.Option>
  448. <Select.Option value={1}>电话</Select.Option>
  449. <Select.Option value={2}>QQ</Select.Option>
  450. <Select.Option value={3}>微信</Select.Option>
  451. <Select.Option value={4}>邮箱</Select.Option>
  452. <Select.Option value={5}>公出打卡</Select.Option>
  453. </Select>
  454. </Form.Item>
  455. <Form.Item style={{ marginTop: '10px' }}>
  456. <Cascaders
  457. ref={ref => this.Cascaders = ref}
  458. placeholder="选择跟进部门"
  459. id="id"
  460. name="name"
  461. children="list"
  462. height={32}
  463. onSel={(e) => {
  464. this.setState({
  465. deps: JSON.stringify(e)
  466. })
  467. }}
  468. />
  469. {/* <Select
  470. placeholder="选择跟进部门"
  471. style={{ width: '200px', marginRight: '10px' }}
  472. value={this.state.depId}
  473. onChange={
  474. (e) => {
  475. this.setState({ depId: e })
  476. }}
  477. notFoundContent="未获取到上级组织列表"
  478. >
  479. {this.state.contactsOption}
  480. </Select> */}
  481. </Form.Item>
  482. <Form.Item label='跟进时间:' style={{ marginTop: '10px' }}>
  483. <RangePicker
  484. style={{ marginRight: '10px' }}
  485. value={[
  486. this.state.releaseDate[0]
  487. ? moment(this.state.releaseDate[0])
  488. : null,
  489. this.state.releaseDate[1]
  490. ? moment(this.state.releaseDate[1])
  491. : null,
  492. ]}
  493. onChange={(data, dataString) => {
  494. this.setState({ releaseDate: dataString });
  495. }}
  496. />
  497. </Form.Item>
  498. <Form.Item label='客户初始时间:' style={{ marginTop: '10px' }}>
  499. <RangePicker
  500. style={{ marginRight: '10px' }}
  501. value={[
  502. this.state.releaseDate1[0]
  503. ? moment(this.state.releaseDate1[0])
  504. : null,
  505. this.state.releaseDate1[1]
  506. ? moment(this.state.releaseDate1[1])
  507. : null,
  508. ]}
  509. onChange={(data, dataString) => {
  510. this.setState({ releaseDate1: dataString });
  511. }}
  512. />
  513. </Form.Item>
  514. <Form.Item label='指导时间:' style={{ marginTop: '10px' }}>
  515. <RangePicker
  516. style={{ marginRight: '10px' }}
  517. value={[
  518. this.state.releaseDate2[0]
  519. ? moment(this.state.releaseDate2[0])
  520. : null,
  521. this.state.releaseDate2[1]
  522. ? moment(this.state.releaseDate2[1])
  523. : null,
  524. ]}
  525. onChange={(data, dataString) => {
  526. this.setState({ releaseDate2: dataString });
  527. }}
  528. />
  529. </Form.Item>
  530. </Form>
  531. <Button
  532. type="primary"
  533. style={{ marginLeft: "10px", marginRight: 10 }}
  534. onClick={() => {
  535. this.loadData();
  536. }}
  537. >
  538. 搜索
  539. </Button>
  540. <Button onClick={this.reset}>重置</Button>
  541. </div>
  542. </TabPane>
  543. <TabPane tab="更改表格显示数据" key="2">
  544. <div style={{ marginLeft: 10 }}>
  545. <ChooseList
  546. columns={this.state.columns}
  547. changeFn={this.changeList}
  548. changeList={this.state.changeList}
  549. top={55}
  550. margin={11}
  551. />
  552. </div>
  553. </TabPane>
  554. <TabPane tab="导出" key="3">
  555. <Button style={{ float: "left", margin: 10 }} onClick={this.export}>
  556. 导出excel
  557. </Button>
  558. </TabPane>
  559. </Tabs>
  560. <div className="patent-table">
  561. <Spin spinning={this.state.loading}>
  562. <Table
  563. columns={
  564. this.state.changeList.length
  565. ? this.state.changeList
  566. : this.state.columns
  567. }
  568. dataSource={this.state.dataSource}
  569. pagination={this.state.pagination}
  570. onRowClick={this.tableRowClick}
  571. style={{
  572. cursor: 'pointer',
  573. }}
  574. />
  575. </Spin>
  576. </div>
  577. <IntentionDetail
  578. isCustomerAdmin={this.props.isCustomerAdmin}
  579. categoryArr={this.state.categoryArr}
  580. IntentionData={this.state.rowData}
  581. modalVisible={this.state.modalVisible}
  582. isGuidanceLv={this.props.isGuidanceLv}
  583. isEditGuidanceLv={this.props.isEditGuidanceLv}
  584. name={this.state.modalName}
  585. closeDesc={this.closeDesc}
  586. />
  587. </div>
  588. )
  589. }
  590. }
  591. export default FollowUpSummary;