channel.jsx 45 KB

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