index.jsx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. import React,{Component} from 'react';
  2. import {
  3. AutoComplete,
  4. Button,
  5. Cascader,
  6. DatePicker,
  7. Icon,
  8. Input,
  9. message,
  10. Modal,
  11. Select,
  12. Spin,
  13. Table,
  14. Tabs,
  15. Tag
  16. } from "antd";
  17. import { citySelect, provinceList } from '@/NewDicProvinceList';
  18. import {getSocialAttribute, beforeUploadFile, getLevel, ShowModal} from "@/tools.js";
  19. import moment from "moment";
  20. import $ from "jquery/src/ajax";
  21. import IntentionDetail from "../../NEW/intentionCustomer/intentionDetail/intentionDetail";
  22. const {TabPane} = Tabs;
  23. const { RangePicker } = DatePicker;
  24. class CustomerFollow extends Component{
  25. constructor(props) {
  26. super(props);
  27. this.state={
  28. nameSearch: '',
  29. provinceSearch: '',
  30. addressSearch: '',
  31. level: '',
  32. releaseDate: [],
  33. selectedRowKeys: [],
  34. provinces: [],
  35. dataSource: [],
  36. categoryArr: [],
  37. modalName: '',
  38. modalVisible: false,
  39. basicState: false,
  40. contactState: false,
  41. rowData: {},
  42. pagination: {
  43. defaultCurrent: 1,
  44. defaultPageSize: 10,
  45. showQuickJumper: true,
  46. pageSize: 10,
  47. onChange: function (page) {
  48. this.loadData(page);
  49. }.bind(this),
  50. showTotal: function (total) {
  51. return "共" + total + "条数据";
  52. },
  53. },
  54. columns: [
  55. {
  56. title: "客户名称",
  57. dataIndex: "name",
  58. key: "name",
  59. },
  60. {
  61. title: "地区",
  62. dataIndex: "locationProvince",
  63. key: "locationProvince",
  64. },
  65. {
  66. title: "联系人",
  67. dataIndex: "contacts",
  68. key: "contacts",
  69. },
  70. {
  71. title: "联系电话",
  72. dataIndex: "contactMobile",
  73. key: "contactMobile",
  74. },
  75. {
  76. title: "社会性质",
  77. dataIndex: "societyTag",
  78. key: "societyTag",
  79. render: (text) => {
  80. return getSocialAttribute(text);
  81. },
  82. },
  83. {
  84. title: "客户初始时间",
  85. dataIndex: "transferTime",
  86. key: "transferTime",
  87. },
  88. {
  89. title: "剩余私有天数",
  90. dataIndex: "surplusFollowTime",
  91. key: "surplusFollowTime",
  92. },
  93. {
  94. title: "剩余签单天数",
  95. dataIndex: "surplusSignTime",
  96. key: "surplusSignTime",
  97. },
  98. {
  99. title: "最新跟进时间",
  100. dataIndex: "lastFollowTime",
  101. key: "lastFollowTime",
  102. },
  103. {
  104. title: "客户等级",
  105. dataIndex: "level",
  106. key: "level",
  107. render: (text) => {
  108. if(text === 0) {
  109. return <Tag color="#87d068">一般客户</Tag>;
  110. }else if(text === 1) {
  111. return <Tag color="#D2691E">意向客户</Tag>;
  112. }else if(text === 2) {
  113. return <Tag color="#FF0000">重点客户</Tag>;
  114. }else {
  115. return "";
  116. }
  117. },
  118. },
  119. {
  120. title: "跟进人",
  121. dataIndex: "null",
  122. key: "null",
  123. },
  124. {
  125. title: "跟进操作",
  126. dataIndex: "abc",
  127. key: "abc",
  128. render: (text, record, index) => {
  129. return (
  130. <div>
  131. <Button
  132. onClick={(e) => {
  133. e.stopPropagation();
  134. this.setState({
  135. guidanceVisible: true
  136. });
  137. }}
  138. type="primary"
  139. >
  140. 指导
  141. </Button>
  142. </div>
  143. );
  144. },
  145. },
  146. ],
  147. loading: false,
  148. ispage: 1,
  149. guidance: '',
  150. };
  151. this.callback = this.callback.bind(this);
  152. this.loadData = this.loadData.bind(this);
  153. this.reset = this.reset.bind(this);
  154. this.tableRowClick = this.tableRowClick.bind(this);
  155. this.closeDesc = this.closeDesc.bind(this);
  156. this.releaseGuidance = this.releaseGuidance.bind(this);
  157. }
  158. componentDidMount() {
  159. this.loadData();
  160. this.category();
  161. //城市
  162. let Province = [];
  163. provinceList.map(function (item) {
  164. let id = String(item.id);
  165. Province.push(
  166. <Select.Option value={id} key={item.name}>
  167. {item.name}
  168. </Select.Option>
  169. );
  170. });
  171. this.setState({
  172. provinces: Province
  173. })
  174. }
  175. callback(){
  176. }
  177. loadData(pageNo) {
  178. this.setState({
  179. loading: true,
  180. });
  181. let api = '/api/admin/customer/listPrivateOrganizationCustomer';
  182. $.ajax({
  183. method: "post",
  184. dataType: "json",
  185. crossDomain: false,
  186. url: globalConfig.context + api,
  187. data: {
  188. pageNo: pageNo || 1,
  189. pageSize: this.state.pagination.pageSize,
  190. level: this.state.level ? this.state.level : undefined,
  191. name: this.state.nameSearch,
  192. province: !this.state.addressSearch.length
  193. ? this.state.provinceSearch
  194. : this.state.addressSearch[0],
  195. city: !this.state.addressSearch.length
  196. ? ""
  197. : this.state.addressSearch[1],
  198. startDate: this.state.releaseDate[0],
  199. endDate: this.state.releaseDate[1],
  200. },
  201. success: function (data) {
  202. let theArr = [];
  203. if (data.error.length || data.data.list == "") {
  204. if (data.error && data.error.length) {
  205. message.warning(data.error[0].message);
  206. }
  207. } else {
  208. for (let i = 0; i < data.data.list.length; i++) {
  209. let thisdata = data.data.list[i];
  210. let diqu =
  211. (thisdata.province == null ? "" : thisdata.province) +
  212. (thisdata.city == null ? "" : "-" + thisdata.city) +
  213. (thisdata.area == null ? "" : "-" + thisdata.area);
  214. thisdata.key = i;
  215. thisdata.id = thisdata.uid;
  216. thisdata.lastFollowTime = thisdata.lastFollowTime && thisdata.lastFollowTime.split(" ")[0];
  217. thisdata.transferTime= thisdata.transferTime && thisdata.transferTime.split(" ")[0];
  218. thisdata.surplusFollowTime= thisdata.surplusFollowTime && thisdata.surplusFollowTime.split(" ")[0];
  219. thisdata.surplusSignTime= thisdata.surplusSignTime && thisdata.surplusSignTime.split(" ")[0];
  220. thisdata.locationProvince= diqu;
  221. theArr.push(thisdata);
  222. }
  223. this.state.pagination.current = data.data.pageNo;
  224. this.state.pagination.total = data.data.totalCount;
  225. if (data.data && data.data.list && !data.data.list.length) {
  226. this.state.pagination.current = 0;
  227. this.state.pagination.total = 0;
  228. }
  229. this.setState({
  230. ispage: data.data.pageNo,
  231. dataSource: theArr,
  232. pagination: this.state.pagination,
  233. });
  234. }
  235. }.bind(this),
  236. }).always(
  237. function () {
  238. this.setState({
  239. loading: false,
  240. });
  241. }.bind(this)
  242. );
  243. };
  244. reset(){
  245. this.setState({
  246. nameSearch: '',
  247. provinceSearch: '',
  248. addressSearch: '',
  249. level: '',
  250. releaseDate: [],
  251. selectedRowKeys: [],
  252. },()=>{
  253. this.loadData();
  254. });
  255. };
  256. //品类数据获取
  257. category() {
  258. $.ajax({
  259. method: "get",
  260. dataType: "json",
  261. crossDomain: false,
  262. url: globalConfig.context + "/api/admin/Varieties/getSuperList",
  263. data: {},
  264. success: function (data) {
  265. let thedata = data.data;
  266. let theArr = [];
  267. if (!thedata) {
  268. if (data.error && data.error.length) {
  269. message.warning(data.error[0].message);
  270. }
  271. } else {
  272. thedata.map(function (item, index) {
  273. theArr.push({
  274. value: item.id,
  275. key: item.cname,
  276. });
  277. });
  278. }
  279. this.setState({
  280. categoryArr: theArr,
  281. });
  282. }.bind(this),
  283. });
  284. }
  285. tableRowClick(record){
  286. this.setState({
  287. selectedRowKeys: [],
  288. modalVisible: true,
  289. basicState: true,
  290. contactState: true,
  291. modalName: record.name,
  292. rowData: record,
  293. });
  294. };
  295. closeDesc(e, s) {
  296. this.setState({
  297. basicState: e,
  298. visitModul: e,
  299. modalVisible: e,
  300. showDesc: e,
  301. })
  302. if (s) {
  303. this.loadData(this.state.ispage);
  304. }
  305. }
  306. //发布指导意见
  307. releaseGuidance(){
  308. if(!this.state.guidance){
  309. message.info('指导意见不能为空')
  310. return;
  311. }
  312. this.setState({
  313. loading: true,
  314. });
  315. let _this = this;
  316. $.ajax({
  317. method: "get",
  318. dataType: "json",
  319. crossDomain: false,
  320. url: globalConfig.context + "/api/admin/customer/pushReleaseUser",
  321. data: {
  322. guidance: this.state.guidance,
  323. },
  324. success: function (data) {
  325. let thedata = data.data;
  326. if (!thedata) {
  327. if (data.error && data.error.length) {
  328. message.warning(data.error[0].message);
  329. }
  330. }else {
  331. message.success("发布成功");
  332. _this.loadData(this.state.ispage);
  333. }
  334. }.bind(this),
  335. }).always(
  336. function () {
  337. this.setState({
  338. loading: false,
  339. });
  340. }.bind(this)
  341. );
  342. }
  343. render() {
  344. return(
  345. <div className="user-content">
  346. <div className="content-title">
  347. <span>客戶跟进管理</span>
  348. </div>
  349. <div className="user-search">
  350. <Tabs
  351. defaultActiveKey="1"
  352. onChange={this.callback}
  353. className="test"
  354. >
  355. <TabPane tab="搜索" key="1">
  356. <Input
  357. placeholder="客户名称"
  358. value={this.state.nameSearch}
  359. style={{ width: 150, marginRight: 10, marginLeft: 10 }}
  360. onChange={(e) => {
  361. this.setState({ nameSearch: e.target.value });
  362. }}
  363. />
  364. <Select
  365. placeholder="省"
  366. style={{ width: 80 }}
  367. value={this.state.provinceSearch}
  368. onChange={(e) => {
  369. this.setState({ provinceSearch: e });
  370. }}
  371. >
  372. {this.state.provinces}
  373. </Select>
  374. <span style={{ marginRight: "10px" }}>
  375. <Cascader
  376. options={citySelect()}
  377. value={this.state.addressSearch}
  378. placeholder="选择城市"
  379. onChange={(e, pre) => {
  380. this.setState({ addressSearch: e });
  381. }}
  382. />
  383. </span>
  384. <Select
  385. style={{ width: 120 }}
  386. value={this.state.level}
  387. onChange={(e) => {
  388. this.setState({ level: e });
  389. }}
  390. placeholder="请选择客户等级"
  391. >
  392. <Select.Option value="0">一般客户</Select.Option>
  393. <Select.Option value="1">意向客户</Select.Option>
  394. <Select.Option value="2">重点客户</Select.Option>
  395. </Select>
  396. <RangePicker
  397. value={[
  398. this.state.releaseDate[0]
  399. ? moment(this.state.releaseDate[0])
  400. : null,
  401. this.state.releaseDate[1]
  402. ? moment(this.state.releaseDate[1])
  403. : null,
  404. ]}
  405. onChange={(data, dataString) => {
  406. this.setState({ releaseDate: dataString });
  407. }}
  408. />
  409. <Button
  410. type="primary"
  411. style={{ marginLeft: "10px", marginRight: 10 }}
  412. onClick={()=>{
  413. this.loadData();
  414. }}
  415. >
  416. 搜索
  417. </Button>
  418. <Button onClick={this.reset}>重置</Button>
  419. </TabPane>
  420. </Tabs>
  421. </div>
  422. <div className="patent-table">
  423. <Spin spinning={this.state.loading}>
  424. <Table
  425. columns={this.state.columns}
  426. dataSource={this.state.dataSource}
  427. // rowSelection={rowSelection}
  428. pagination={this.state.pagination}
  429. onRowClick={this.tableRowClick}
  430. />
  431. </Spin>
  432. </div>
  433. <IntentionDetail
  434. isGuidanceLv={this.props.isGuidanceLv}
  435. categoryArr={this.state.categoryArr}
  436. detailApi={this.props.detailApi}
  437. IntentionData={this.state.rowData}
  438. modalVisible={this.state.modalVisible}
  439. name={this.state.modalName}
  440. closeDesc={this.closeDesc}
  441. basicState={this.state.basicState}
  442. contactState={this.state.contactState}
  443. />
  444. <Modal
  445. className="customeDetails"
  446. title="指导意见"
  447. width='500px'
  448. visible={this.state.guidanceVisible}
  449. onOk={()=>{
  450. this.setState({
  451. guidanceVisible: false,
  452. guidance: '',
  453. },()=>{
  454. this.loadData(this.state.ispage);
  455. })
  456. }}
  457. onCancel={()=>{
  458. this.setState({
  459. guidanceVisible: false,
  460. guidance: '',
  461. },()=>{
  462. this.loadData(this.state.ispage);
  463. })
  464. }}
  465. footer=''
  466. >
  467. <Spin spinning={this.state.loading}>
  468. <div style={{
  469. display:'flex',
  470. flexFlow:'column',
  471. }}>
  472. <Input
  473. style={{ width: '400px',height:'50px' }}
  474. placeholder="请输入指导意见"
  475. type={'textarea'}
  476. onChange={(e)=>{
  477. this.setState({
  478. guidance: e.target.value,
  479. })
  480. }}
  481. />
  482. <Button
  483. type="primary"
  484. style={{ marginTop: "10px", marginBottom: '10px' }}
  485. onClick={()=>{
  486. this.releaseGuidance();
  487. }}
  488. >
  489. 确定
  490. </Button>
  491. </div>
  492. </Spin>
  493. </Modal>
  494. </div>
  495. )
  496. }
  497. }
  498. export default CustomerFollow;