channel.jsx 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131
  1. import React,{Component} from "react";
  2. import {
  3. AutoComplete,
  4. Button,
  5. Cascader,
  6. DatePicker,
  7. Input,
  8. message,
  9. Select,
  10. Spin,
  11. Table,
  12. Tabs,
  13. Tooltip,
  14. Upload,
  15. Modal, Tag
  16. } from "antd";
  17. import {ChooseList} from "../../../order/orderNew/chooseList";
  18. import $ from "jquery/src/ajax";
  19. import {
  20. getSocialAttribute,
  21. ShowModal,
  22. getChannelAllocationStatus
  23. } from "@/tools.js";
  24. import {
  25. channelAllocationStatus
  26. } from "@/dataDic.js";
  27. import { citySelect, provinceList } from '@/NewDicProvinceList';
  28. import moment from "moment";
  29. import FollowDetail from "./followDetail";
  30. import IntentionDetail from "./intentionDetail/intentionDetail";
  31. import TransferRecords from './transferRecords';
  32. import DuplicateData from './duplicateData';
  33. import OperationTips from './operationTips';
  34. import ShowModalDiv from "@/showModal.jsx";
  35. import './channel.less';
  36. const {TabPane} = Tabs;
  37. const { RangePicker } = DatePicker;
  38. const Option = Select.Option;
  39. class Channel extends Component{
  40. constructor(props) {
  41. super(props);
  42. this.state={
  43. isGuidance:false,
  44. isEditGuidance: true,
  45. upLoadFileLoading:false,
  46. channelAllocationStatusList : channelAllocationStatus.slice(0,channelAllocationStatus.length-2),
  47. columns: [
  48. {
  49. title: "客户名称",
  50. dataIndex: "userName",
  51. key: "userName",
  52. render: (text,record) => {
  53. return (
  54. <span>
  55. {record.recovery === 1 ? <div style={{
  56. background:'#ef7207',
  57. color:'#FFF',
  58. padding: '1px 7px',
  59. borderRadius:'5px',
  60. fontSize:'12px',
  61. display: 'inline-block',
  62. marginRight:'10px'
  63. }}>
  64. 回收
  65. </div> : null}
  66. {text}
  67. </span>
  68. )
  69. },
  70. },
  71. {
  72. title: "地区",
  73. dataIndex: "locationProvince",
  74. key: "locationProvince",
  75. },
  76. {
  77. title: "社会性质",
  78. dataIndex: "societyTag",
  79. key: "societyTag",
  80. render: (text) => {
  81. return getSocialAttribute(text);
  82. },
  83. },
  84. {
  85. title: "渠道专员",
  86. dataIndex: "channelName",
  87. key: "channelName",
  88. },
  89. {
  90. title: "客户联系人",
  91. dataIndex: "contacts",
  92. key: "contacts",
  93. },
  94. {
  95. title: "联系电话",
  96. dataIndex: "contactMobile",
  97. key: "contactMobile",
  98. },
  99. {
  100. title: "渠道初始时间",
  101. dataIndex: "createTimes",
  102. key: "createTimes",
  103. },
  104. {
  105. title: "分配状态",
  106. dataIndex: "status",
  107. key: "status",
  108. render: (text) => (
  109. getChannelAllocationStatus(text,true)
  110. )
  111. },
  112. ],
  113. changeList:[],
  114. dataSource:[],
  115. pagination: {
  116. defaultCurrent: 1,
  117. defaultPageSize: 10,
  118. showQuickJumper: true,
  119. pageSize: 10,
  120. onChange: function (page) {
  121. this.loadData(page);
  122. }.bind(this),
  123. showTotal: function (total) {
  124. return "共" + total + "条数据";
  125. },
  126. },
  127. pageNo:1,
  128. listLoading:false,
  129. selectedRowKeys:[],
  130. selectedRows:[],
  131. modalVisible:false,
  132. nameSearch:'',
  133. statusSearch:undefined,
  134. provinceSearch:undefined,
  135. addressSearch:[],
  136. releaseDate:[],
  137. upLoad: {
  138. customRequest: (options) => {
  139. this.setState({
  140. upLoadFileLoading: true,
  141. })
  142. let params = new FormData();
  143. params.append("file", options.file);
  144. $.ajax({
  145. method: "post",
  146. url: globalConfig.context + "/api/user/channel/import",
  147. async: true,
  148. cache: false,
  149. contentType: false,
  150. processData: false,
  151. data:params
  152. }).done(
  153. function (data) {
  154. this.setState({
  155. upLoadFileLoading: false,
  156. })
  157. if (data.error.length === 0) {
  158. if(data.data === 1){
  159. message.success("导入成功!");
  160. }else if(data.data.list.length > 0){
  161. message.warning('已成功导入!错误/重复客户无法导入,请查看错误渠道数据!');
  162. this.setState({
  163. duplicateData: [],
  164. duplicateDataVisible: true
  165. })
  166. }
  167. this.loadData();
  168. } else {
  169. message.warning(data.error[0].message);
  170. this.loadData();
  171. }
  172. }.bind(this)
  173. ).always(
  174. function () {
  175. this.loadData();
  176. this.setState({
  177. upLoadFileLoading: false,
  178. });
  179. }.bind(this)
  180. );
  181. },
  182. name: "file",
  183. action: globalConfig.context + "/api/user/channel/import",
  184. },
  185. followData: '',
  186. visitModul: false,
  187. categoryArr:[],
  188. tabsKey:'',
  189. adminList:[],
  190. }
  191. this.loadData = this.loadData.bind(this);
  192. this.search = this.search.bind(this);
  193. this.reset = this.reset.bind(this);
  194. this.changeList = this.changeList.bind(this);
  195. this.download = this.download.bind(this);
  196. this.category = this.category.bind(this);
  197. this.closeDesc = this.closeDesc.bind(this);
  198. this.guidanceRead = this.guidanceRead.bind(this);
  199. this.tableRowClick = this.tableRowClick.bind(this);
  200. this.detailCloseDesc = this.detailCloseDesc.bind(this);
  201. this.supervisor = this.supervisor.bind(this);
  202. this.httpChange = this.httpChange.bind(this);
  203. this.blurChange = this.blurChange.bind(this);
  204. this.selectAuto = this.selectAuto.bind(this);
  205. this.changeAssigner = this.changeAssigner.bind(this);
  206. this.getAdminList = this.getAdminList.bind(this);
  207. }
  208. componentWillReceiveProps (nextProps) {
  209. let next = JSON.stringify(nextProps);
  210. let props = JSON.stringify(this.props);
  211. if(next !== props){
  212. location.reload();
  213. }
  214. }
  215. componentDidMount() {
  216. this.initialization();
  217. }
  218. //获取渠道专员列表
  219. getAdminList(value = '') {
  220. this.setState({
  221. adminListLoading:true
  222. })
  223. $.ajax({
  224. method: "get",
  225. dataType: "json",
  226. crossDomain: false,
  227. url: globalConfig.context + "/api/admin/superviser/adminList",
  228. data: {
  229. pageNo: 1,
  230. pageSize: 99,
  231. name: value,
  232. roleName: '渠道专员',
  233. },
  234. success: function (data) {
  235. let thedata = data.data.list;
  236. let theArr = [];
  237. if (data.error && data.error.length) {
  238. message.warning(data.error[0].message);
  239. }else{
  240. thedata.map(function (item, _) {
  241. theArr.push({
  242. value: item.id,
  243. label: item.name,
  244. });
  245. });
  246. }
  247. this.setState({
  248. adminList: theArr,
  249. });
  250. }.bind(this),
  251. }).always(
  252. function () {
  253. this.setState({
  254. adminListLoading:false
  255. })
  256. }.bind(this)
  257. );
  258. }
  259. initialization(){
  260. //城市
  261. let provinces = [];
  262. provinceList.map(function (item) {
  263. var id = String(item.id);
  264. provinces.push(
  265. <Select.Option value={id} key={item.name}>
  266. {item.name}
  267. </Select.Option>
  268. );
  269. });
  270. this.setState({
  271. provinces
  272. })
  273. this.loadData();
  274. this.category();
  275. if(this.props.type === 0 || this.props.type === 3){
  276. this.state.columns.push({
  277. title: "分配时间",
  278. dataIndex: "distributionTimes",
  279. key: "distributionTimes",
  280. });
  281. this.state.columns.push({
  282. title: "剩余签单(天)",
  283. dataIndex: "days",
  284. key: "days",
  285. render: (text,record) => (
  286. record.status !== 7 ? <Tag color='#f00'>{text}天</Tag> : ''
  287. )
  288. });
  289. }
  290. if(this.props.followUp){
  291. this.state.columns.push({
  292. title: "当前跟进人",
  293. dataIndex: "adminName",
  294. key: "adminName",
  295. render: (text, record) => {
  296. return (
  297. record.status !== 0 ? text : ''
  298. )
  299. }
  300. });
  301. this.state.columns.push({
  302. title: "跟进操作",
  303. dataIndex: "abc",
  304. key: "abc",
  305. render: (text, record, index) => {
  306. return (
  307. <div style={{
  308. display: 'flex',
  309. flexFlow:'row',
  310. alignItems:'center',
  311. }}>
  312. <Button
  313. disabled={this.props.deliver === 2 && record.status === 2 && this.props.isEditGuidanceLv}
  314. onClick={(e) => {
  315. e.stopPropagation();
  316. if(this.props.isEditGuidanceLv){
  317. this.visit(record);
  318. }else{
  319. this.tableRowClick(record);
  320. }
  321. }}
  322. type="primary"
  323. >
  324. {this.props.isEditGuidanceLv ? '客户跟进' : '查看指导'}
  325. </Button>
  326. </div>
  327. );
  328. },
  329. });
  330. if(this.props.isEditGuidanceLv){
  331. this.state.columns.push({
  332. title: "指导意见",
  333. dataIndex: "guidance",
  334. key: "guidance",
  335. render: (text, record, index) => {
  336. return (
  337. <div style={{
  338. display: 'flex',
  339. flexFlow:'row',
  340. alignItems:'center',
  341. }}>
  342. {/*指导 0无 1未读 2已读*/}
  343. {text === 1 || text === 2 ? <Button
  344. style={text === 1 ? {
  345. background:'#F00000',
  346. borderColor:'#F00000'
  347. } : {}}
  348. onClick={(e)=>{
  349. e.stopPropagation();
  350. this.guidanceRead(record.uid).then(()=>{
  351. this.setState({
  352. tabsKey:"4",
  353. },()=>{
  354. this.tableRowClick(record)
  355. })
  356. })
  357. }}
  358. type="primary"
  359. >
  360. {text === 1 ? '未读' : '查看'}
  361. </Button> : <div>暂无指导</div>}
  362. </div>
  363. );
  364. },
  365. });
  366. }
  367. }
  368. this.state.columns.push({
  369. title: "备注",
  370. dataIndex: "remarks",
  371. key: "remarks",
  372. render: (text) => {
  373. return (
  374. <Tooltip placement="topLeft" title={text}>
  375. <div style={{
  376. maxWidth:'150px',
  377. overflow:'hidden',
  378. textOverflow: "ellipsis",
  379. whiteSpace:'nowrap',
  380. }}>{text}</div>
  381. </Tooltip>
  382. )
  383. }
  384. });
  385. this.setState({
  386. columns:this.state.columns
  387. })
  388. }
  389. visit(e) {
  390. this.setState({
  391. followData: e,
  392. visitModul: true,
  393. });
  394. }
  395. loadData(pageNo = 1) {
  396. this.setState({
  397. listLoading: true,
  398. selectedRows: [],
  399. selectedRowKeys: [],
  400. });
  401. $.ajax({
  402. method: "post",
  403. dataType: "json",
  404. crossDomain: false,
  405. url: globalConfig.context + '/api/admin/customer/listChannelCustomer',
  406. data: {
  407. type:this.props.type,
  408. pageNo: pageNo || 1,
  409. pageSize: this.state.pagination.pageSize,
  410. name: this.state.nameSearch,
  411. status:this.state.statusSearch,
  412. province: !this.state.addressSearch.length
  413. ? this.state.provinceSearch
  414. : this.state.addressSearch[0],
  415. city: !this.state.addressSearch.length
  416. ? ""
  417. : this.state.addressSearch[1],
  418. startTime: this.state.releaseDate[0],
  419. endTime: this.state.releaseDate[1],
  420. aid:this.state.adminValue,
  421. },
  422. success: function (data) {
  423. ShowModal(this);
  424. let theArr = [];
  425. if (data.error.length > 0) {
  426. message.warning(data.error[0].message);
  427. } else {
  428. if(data.data.list.length === 0 && pageNo !== 1){
  429. this.loadData(pageNo - 1)
  430. }else{
  431. for (let i = 0; i < data.data.list.length; i++) {
  432. let thisdata = data.data.list[i];
  433. let diqu =
  434. (thisdata.province == null ? "" : thisdata.province) +
  435. (thisdata.city == null ? "" : "-" + thisdata.city) +
  436. (thisdata.area == null ? "" : "-" + thisdata.area);
  437. thisdata.key = i;
  438. thisdata.id = thisdata.uid;
  439. thisdata.lastFollowTime = thisdata.lastFollowTime &&
  440. thisdata.lastFollowTime.split(" ")[0];
  441. thisdata.transferTime= thisdata.transferTime && thisdata.transferTime.split(" ")[0];
  442. thisdata.surplusFollowTime = thisdata.surplusFollowTime && thisdata.surplusFollowTime.split(" ")[0];
  443. thisdata.surplusSignTime = thisdata.surplusSignTime && thisdata.surplusSignTime.split(" ")[0];
  444. thisdata.locationProvince = diqu;
  445. theArr.push(thisdata);
  446. }
  447. this.state.pagination.current = data.data.pageNo;
  448. this.state.pagination.total = data.data.totalCount;
  449. this.setState({
  450. pageNo: data.data.pageNo,
  451. dataSource: theArr,
  452. pagination: this.state.pagination,
  453. })
  454. }
  455. }
  456. }.bind(this),
  457. }).always(
  458. function () {
  459. this.setState({
  460. listLoading: false,
  461. });
  462. }.bind(this)
  463. );
  464. }
  465. search(){
  466. this.loadData();
  467. }
  468. reset(){
  469. this.setState({
  470. nameSearch:'',
  471. provinceSearch:undefined,
  472. addressSearch:[],
  473. releaseDate:[],
  474. statusSearch:undefined,
  475. adminValue:undefined,
  476. },()=>{
  477. this.loadData();
  478. })
  479. }
  480. download() {
  481. window.location.href =
  482. globalConfig.context +
  483. "/api/user/channel/downloadTemplate?" +
  484. "sign=user_channel";
  485. }
  486. changeList(arr) {
  487. const newArr = [];
  488. this.state.columns.forEach(item => {
  489. arr.forEach(val => {
  490. if (val === item.title) {
  491. newArr.push(item);
  492. }
  493. });
  494. });
  495. this.setState({
  496. changeList: newArr
  497. });
  498. }
  499. category() {
  500. $.ajax({
  501. method: "get",
  502. dataType: "json",
  503. crossDomain: false,
  504. url: globalConfig.context + "/api/admin/Varieties/getSuperList",
  505. data: {},
  506. success: function (data) {
  507. let thedata = data.data;
  508. let theArr = [];
  509. if (!thedata) {
  510. if (data.error && data.error.length) {
  511. message.warning(data.error[0].message);
  512. }
  513. thedata = {};
  514. } else {
  515. thedata.map(function (item, index) {
  516. theArr.push({
  517. value: item.id,
  518. key: item.cname,
  519. });
  520. });
  521. }
  522. this.setState({
  523. categoryArr: theArr,
  524. });
  525. }.bind(this),
  526. });
  527. }
  528. closeDesc(){
  529. this.setState({
  530. categoryArr:[],
  531. followData:'',
  532. visitModul:false
  533. })
  534. }
  535. //已读指导记录
  536. guidanceRead(id) {
  537. return new Promise((resolve,reject)=>{
  538. $.ajax({
  539. method: "post",
  540. dataType: "json",
  541. crossDomain: false,
  542. url: globalConfig.context + "/api/admin/customer/pushGuidance",
  543. data: {
  544. uid: id,
  545. }
  546. }).done(function(data) {
  547. if(!data.error.length) {
  548. resolve();
  549. } else {
  550. message.warning(data.error[0].message);
  551. reject();
  552. };
  553. }.bind(this));
  554. })
  555. }
  556. tableRowClick(record) {
  557. if(this.props.deliver === 2 && record.status === 2 && this.props.isEditGuidanceLv){
  558. this.setState({
  559. isGuidance: true,
  560. tabsKey:"4",
  561. })
  562. }
  563. //营销经理人员 取消指导自己的操作
  564. if(this.props.deliver === 2 && record.status === 1 && this.props.isEditGuidanceLv){
  565. this.setState({
  566. isEditGuidance: false,
  567. })
  568. }
  569. //营销人员 取消指导的操作
  570. if(this.props.deliver === 0 && record.status === 2 && this.props.isEditGuidanceLv){
  571. this.setState({
  572. isEditGuidance: false,
  573. })
  574. }
  575. this.setState({
  576. rowData:record,
  577. modalVisible: true,
  578. basicState: true,
  579. contactState: true,
  580. modalName: record.userName
  581. })
  582. }
  583. detailCloseDesc(){
  584. this.setState({
  585. rowData:'',
  586. modalVisible: false,
  587. basicState: false,
  588. contactState: false,
  589. modalName: '',
  590. isGuidance: false,
  591. isEditGuidance: true,
  592. tabsKey: '',
  593. },()=>{
  594. this.loadData(this.state.pageNo);
  595. })
  596. }
  597. supervisor(e) {
  598. $.ajax({
  599. method: "get",
  600. dataType: "json",
  601. crossDomain: false,
  602. url: globalConfig.context + "/api/admin/customer/listAdminByName",
  603. data: {
  604. adminName: e,
  605. },
  606. success: function (data) {
  607. let thedata = data.data;
  608. if (!thedata) {
  609. if (data.error && data.error.length) {
  610. message.warning(data.error[0].message);
  611. }
  612. thedata = {};
  613. }
  614. this.setState({
  615. customerArr: thedata,
  616. });
  617. }.bind(this),
  618. }).always(
  619. function () {
  620. }.bind(this)
  621. );
  622. }
  623. httpChange(e) {
  624. if (e.length >= 1) {
  625. this.supervisor(e);
  626. }
  627. this.setState({
  628. auto: e,
  629. });
  630. }
  631. blurChange(e) {
  632. let theType = "";
  633. let contactLists = this.state.customerArr || [];
  634. if (e) {
  635. contactLists.map(function (item) {
  636. if (item.name == e.toString()) {
  637. theType = item.id;
  638. }
  639. });
  640. }
  641. this.setState({
  642. theTypes: theType,
  643. });
  644. }
  645. selectAuto(value, options) {
  646. this.setState({
  647. auto: value,
  648. });
  649. }
  650. changeAssigner(remarks,type,lv) {
  651. //type 0 总监分配 1经理分配 2回收
  652. let arr = this.state.selectedRows.filter(v=>v.status === 1);
  653. let arr1 = this.state.selectedRows.filter(v=>v.status === 2);
  654. let arr2 = this.state.selectedRows.filter(v=>v.status === 7);
  655. let arr3 = this.state.selectedRows.filter(v=>v.status === 6);
  656. if(type === 0 && (arr.length>0 || arr1.length>0)){
  657. message.warning('选中的信息中存在“已分配”数据,请取消这些选项后重新提交')
  658. return;
  659. }
  660. if(type === 1 && arr1.length>0){
  661. message.warning('选中的信息中存在“经理已分配”数据,请取消这些选项后重新提交')
  662. return;
  663. }
  664. //处于回收状态的客户经理和营销员不能点击回收
  665. if(this.props.deliver !== 1 && arr3.length>0){
  666. message.warning('渠道客户已回收!待营销总监,重新分配')
  667. return;
  668. }
  669. //this.props.deliver && this.props.recovery 用于判断是否为经理
  670. if(this.props.deliver === 2 && this.props.recovery && type === 2 && arr1.length>0){
  671. message.warning('操作失败,存在客户已被分配营销员')
  672. return;
  673. }
  674. if(arr2.length>0){
  675. message.warning('不能操作已签单客户')
  676. return;
  677. }
  678. if(!remarks){
  679. message.warning(type === 1 ? "请输入分配原因" : type === 2 ? "请输入回收原因" : type === 0 ? "请输入分配原因" : "");
  680. return;
  681. }
  682. if (this.state.theTypes || lv) {
  683. this.setState({
  684. listLoading: true,
  685. })
  686. let changeIds = '';
  687. let oldAid = '';
  688. for (let idx = 0; idx < this.state.selectedRows.length; idx++) {
  689. let rowItem = this.state.selectedRows[idx];
  690. if(rowItem.recovery === 1 && type === 2){
  691. let arr = this.state.selectedRows.filter(v => v.recovery === 1)
  692. Modal.info({
  693. title: '以下数据属于回收再分配资源,无法再次回收',
  694. content: (
  695. <div>
  696. {
  697. arr.map(i=>(
  698. <div style={{paddingBottom:'7px'}}>{i.userName}</div>
  699. ))
  700. }
  701. </div>
  702. ),
  703. onOk() {},
  704. });
  705. return ;
  706. }
  707. if (rowItem.id) {
  708. oldAid = rowItem.aid;
  709. changeIds = this.state.selectedRows.length-1 === idx ? changeIds +rowItem.id : changeIds + rowItem.id + ',' ;
  710. }
  711. }
  712. $.ajax({
  713. method: "post",
  714. dataType: "json",
  715. crossDomain: false,
  716. url: globalConfig.context + "/api/admin/customer/channelCustomerDeliver",
  717. data: {
  718. userIds: changeIds, //这一行数据的ID
  719. receiveId: this.state.theTypes, //指定分配人的ID
  720. remarks: remarks,
  721. type, //0总监分配 1经理分配 2回收
  722. },
  723. }).done(
  724. function (data) {
  725. this.setState({
  726. listLoading: false,
  727. })
  728. if (!data.error.length) {
  729. message.success(type === 1 ? "分配成功!" : type === 2 ? "回收成功!" : type === 0 ? "分配成功!" : "");
  730. this.setState({
  731. auto: "",
  732. loading: false,
  733. selectedRowKeys: [],
  734. visible:false,
  735. recoveryVisible: false,
  736. },()=>{
  737. this.loadData(this.state.pageNo);
  738. });
  739. } else {
  740. message.warning(data.error[0].message);
  741. }
  742. }.bind(this)
  743. );
  744. } else {
  745. message.warning("请输入分配人姓名");
  746. }
  747. }
  748. render() {
  749. const rowSelection = {
  750. hideDefaultSelections: true,
  751. selectedRowKeys: this.state.selectedRowKeys,
  752. onChange: (selectedRowKeys, selectedRows) => {
  753. this.setState({
  754. modalVisible: false,
  755. selectedRows: selectedRows,
  756. selectedRowKeys: selectedRowKeys,
  757. });
  758. },
  759. onSelect: (recordt, selected, selectedRows) => {
  760. this.setState({
  761. modalVisible: false,
  762. });
  763. },
  764. };
  765. const dataSources = this.state.customerArr || [];
  766. const options = dataSources.map((group) => (
  767. <Select.Option key={group.id} value={group.name}>
  768. {group.name}
  769. </Select.Option>
  770. ));
  771. const hasSelected = this.state.selectedRowKeys.length > 0;
  772. return (
  773. <div className="user-content">
  774. <ShowModalDiv ShowModal={this.state.showModal} />
  775. <div className="content-title">
  776. <span>渠道客户</span>
  777. </div>
  778. <div className="user-search">
  779. <Tabs
  780. defaultActiveKey="1"
  781. className="test"
  782. >
  783. <TabPane tab="搜索" key="1">
  784. <Input
  785. placeholder="请输入客户名称"
  786. value={this.state.nameSearch}
  787. style={{ width: 150, marginRight: 10, marginLeft: 10 }}
  788. onChange={(e) => {
  789. this.setState({ nameSearch: e.target.value });
  790. }}
  791. />
  792. <Select
  793. placeholder="分配状态"
  794. style={{ width: 170 }}
  795. value={this.state.statusSearch}
  796. onChange={(e) => {
  797. this.setState({ statusSearch: e });
  798. }}
  799. >
  800. {
  801. this.state.channelAllocationStatusList.map((v,key)=>(
  802. <Select.Option value={v.value} key={key}>
  803. {v.key}
  804. </Select.Option>
  805. ))
  806. }
  807. </Select>
  808. <Select
  809. placeholder="省"
  810. style={{ width: 80 }}
  811. value={this.state.provinceSearch}
  812. onChange={(e) => {
  813. this.setState({ provinceSearch: e });
  814. }}
  815. >
  816. {this.state.provinces}
  817. </Select>
  818. <span style={{ marginRight: "10px" }}>
  819. <Cascader
  820. options={citySelect()}
  821. value={this.state.addressSearch}
  822. placeholder="选择城市"
  823. onChange={(e, pre) => {
  824. this.setState({ addressSearch: e });
  825. }}
  826. />
  827. </span>
  828. <RangePicker
  829. value={[
  830. this.state.releaseDate[0]
  831. ? moment(this.state.releaseDate[0])
  832. : null,
  833. this.state.releaseDate[1]
  834. ? moment(this.state.releaseDate[1])
  835. : null,
  836. ]}
  837. onChange={(data, dataString) => {
  838. this.setState({ releaseDate: dataString });
  839. }}
  840. />
  841. {this.props.type !== 1 ? <Select
  842. showSearch
  843. value={this.state.adminValue}
  844. style={{ width: 150,marginLeft:'10px' }}
  845. onSearch={this.getAdminList}
  846. onSelect={(v)=>{
  847. this.setState({
  848. adminValue:v
  849. })
  850. }}
  851. onFocus={this.getAdminList}
  852. filterOption={false}
  853. placeholder="请输入渠道专员名称"
  854. >
  855. {this.state.adminList.map((v,k)=>(
  856. <Option key={k} value={v.value}>{v.label}</Option>
  857. ))}
  858. </Select> : null}
  859. <Button
  860. type="primary"
  861. style={{ marginLeft: "10px", marginRight: 10 }}
  862. onClick={this.search}
  863. >
  864. 搜索
  865. </Button>
  866. <Button onClick={this.reset}>重置</Button>
  867. </TabPane>
  868. <TabPane tab="操作" key="2">
  869. <div style={{
  870. marginTop: 10,
  871. }}>
  872. {this.props.deliver ? <AutoComplete
  873. className="certain-category-search"
  874. dropdownClassName="certain-category-search-dropdown"
  875. dropdownMatchSelectWidth={false}
  876. dropdownStyle={{ width: 120 }}
  877. style={{ width: "120px" }}
  878. dataSource={options}
  879. placeholder={this.props.deliver === 1 ? '输入分配人姓名' : '输入分配人姓名'}
  880. value={this.state.auto}
  881. onChange={this.httpChange}
  882. filterOption={true}
  883. onBlur={this.blurChange}
  884. onSelect={this.selectAuto}
  885. disabled={!hasSelected}
  886. >
  887. <Input />
  888. </AutoComplete> : ''}
  889. {this.props.deliver ? <Button
  890. type="primary"
  891. onClick={(e) => {
  892. e.stopPropagation();
  893. this.setState({
  894. visible:true
  895. })
  896. }}
  897. disabled={!hasSelected}
  898. style={{ marginRight: 10 }}
  899. >
  900. {this.props.deliver === 1 ? '分配' : '分配'}
  901. </Button> : ''}
  902. {this.props.recovery ? <Button
  903. type="primary"
  904. onClick={(e) => {
  905. e.stopPropagation();
  906. this.setState({
  907. recoveryVisible:true
  908. })
  909. }}
  910. disabled={!hasSelected}
  911. style={{ marginRight: 10 }}
  912. >
  913. 回收
  914. </Button> : ''}
  915. {this.props.deliver || this.props.recovery ? <Button
  916. type="primary"
  917. onClick={(e) => {
  918. e.stopPropagation();
  919. this.setState({
  920. transferVisible:true,
  921. transferId: this.state.selectedRows[0].uid
  922. })
  923. }}
  924. disabled={!hasSelected || this.state.selectedRows.length > 1}
  925. style={{ marginRight: 10 }}
  926. >
  927. 日志
  928. </Button> : ''}
  929. {this.props.channel ? <Upload {...this.state.upLoad} disabled={this.state.upLoadFileLoading}>
  930. <Button
  931. loading={this.state.upLoadFileLoading}
  932. type="primary"
  933. style={{ marginRight: "10px" }}
  934. >
  935. +批量导入渠道客户
  936. </Button>
  937. </Upload> : null}
  938. {this.props.channel ? <Button
  939. onClick={(e) => {
  940. e.stopPropagation();
  941. this.download();
  942. }}
  943. type="primary"
  944. style={{
  945. marginRight: "10px",
  946. background:'#f49f36',
  947. borderColor:'#f49f36'
  948. }}
  949. >
  950. 下载渠道客户模板
  951. </Button> : ''}
  952. {this.props.channel ? <Button
  953. onClick={(e) => {
  954. e.stopPropagation();
  955. this.setState({
  956. duplicateData: [],
  957. duplicateDataVisible: true
  958. })
  959. }}
  960. type="primary"
  961. style={{
  962. marginRight: "10px",
  963. background:'#ff2f00',
  964. borderColor:'#ff2f00'
  965. }}
  966. >
  967. 查看导入失败列表
  968. </Button> : ''}
  969. </div>
  970. </TabPane>
  971. <TabPane tab="更改表格显示数据" key="3">
  972. <div style={{ marginLeft: 10 }}>
  973. <ChooseList
  974. columns={this.state.columns}
  975. changeFn={this.changeList}
  976. changeList={this.state.changeList}
  977. top={55}
  978. margin={11}
  979. />
  980. </div>
  981. </TabPane>
  982. </Tabs>
  983. </div>
  984. <div className="patent-table">
  985. <Spin spinning={this.state.listLoading}>
  986. <Table
  987. size="middle"
  988. className={'intentionCustomerTable'}
  989. columns={
  990. this.state.changeList.length !== 0
  991. ? this.state.changeList
  992. : this.state.columns
  993. }
  994. dataSource={this.state.dataSource}
  995. rowSelection={this.props.deliver || this.props.recovery ? rowSelection : ''}
  996. pagination={this.state.pagination}
  997. onRowDoubleClick={this.tableRowClick}
  998. />
  999. </Spin>
  1000. </div>
  1001. <FollowDetail
  1002. categoryArr={this.state.categoryArr}
  1003. followData={this.state.followData}
  1004. visitModul={this.state.visitModul}
  1005. closeDesc={this.closeDesc}
  1006. />
  1007. <IntentionDetail
  1008. tabsKey={this.state.tabsKey}
  1009. categoryArr={this.state.categoryArr}
  1010. detailApi={this.props.detailApi}
  1011. IntentionData={this.state.rowData}
  1012. modalVisible={this.state.modalVisible}
  1013. name={this.state.modalName}
  1014. closeDesc={this.detailCloseDesc}
  1015. basicState={this.state.basicState}
  1016. contactState={this.state.contactState}
  1017. isGuidanceLv={this.props.isGuidanceLv || this.state.isGuidance}
  1018. isEditGuidanceLv={this.props.isEditGuidanceLv && this.state.isEditGuidance}
  1019. />
  1020. {this.state.duplicateDataVisible ? <DuplicateData
  1021. duplicateData={this.state.duplicateData || []}
  1022. visible={this.state.duplicateDataVisible}
  1023. onCancel={()=>{
  1024. this.setState({
  1025. duplicateData:[],
  1026. duplicateDataVisible: false
  1027. },()=>{
  1028. this.loadData(this.state.pageNo);
  1029. })
  1030. }}
  1031. /> : null}
  1032. {this.state.transferVisible || this.state.returnVisible ? <TransferRecords
  1033. type={this.state.transferVisible ? (this.props.deliver === 1 ? 0 : 1) : this.state.returnVisible ? 2 : 0}
  1034. id={this.state.transferId}
  1035. visible={this.state.transferVisible || this.state.returnVisible}
  1036. cancel={()=>{
  1037. this.setState({
  1038. transferVisible:false,
  1039. returnVisible: false,
  1040. transferId:''
  1041. })
  1042. }}
  1043. /> : '' }
  1044. {/*渠道客户分配*/}
  1045. {this.state.visible ? <OperationTips
  1046. title={'渠道客户分配'}
  1047. selectedRows={this.state.selectedRows}
  1048. visible={this.state.visible}
  1049. onOk={(value)=>{
  1050. // 0 总监分配 1经理分配 2回收
  1051. this.changeAssigner(value,this.props.deliver === 1 ? 0 : this.props.deliver === 2 ? 1 : '')
  1052. }}
  1053. onCancel={()=>{
  1054. this.setState({
  1055. visible:false
  1056. })
  1057. }}/> : ''}
  1058. {/*渠道客户回收*/}
  1059. {this.state.recoveryVisible ? <OperationTips
  1060. title={'渠道客户回收'}
  1061. selectedRows={this.state.selectedRows}
  1062. visible={this.state.recoveryVisible}
  1063. onOk={(value)=>{
  1064. this.changeAssigner(value,2,true)
  1065. }}
  1066. onCancel={()=>{
  1067. this.setState({
  1068. recoveryVisible:false
  1069. })
  1070. }}/> : ''}
  1071. {this.state.upLoadFileLoading ? <div style={{
  1072. position:'fixed',
  1073. display:'flex',
  1074. flexFlow:'column',
  1075. justifyContent:'center',
  1076. alignItems:'center',
  1077. top:0,
  1078. bottom:0,
  1079. left:0,
  1080. right:0,
  1081. background:'rgba(0,0,0,.7)',
  1082. color:"#58a3ff",
  1083. fontSize:'20px',
  1084. zIndex:99999,
  1085. }}>
  1086. <Spin spinning={this.state.upLoadFileLoading}/>
  1087. <div style={{paddingTop:'10px'}}>客户名称匹配中...</div>
  1088. </div>: null}
  1089. </div>
  1090. )
  1091. }
  1092. }
  1093. export default Channel;