signCustomer.jsx 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. import React from 'react';
  2. import {
  3. Radio,
  4. Icon,
  5. Button,
  6. AutoComplete,
  7. Cascader,
  8. Input,
  9. Select,
  10. Tabs,
  11. Spin,
  12. Popconfirm,
  13. Table,
  14. Switch,
  15. message,
  16. DatePicker,
  17. Upload,
  18. Form,
  19. Modal
  20. } from 'antd';
  21. import ajax from 'jquery/src/ajax/xhr.js';
  22. import $ from 'jquery/src/ajax';
  23. import moment from 'moment';
  24. import { citySelect, provinceList } from '@/NewDicProvinceList';
  25. import { socialAttribute, industry, auditStatusL, lvl, currentMember } from '@/dataDic.js';
  26. import { getSocialAttribute, beforeUploadFile, ShowModal } from "@/tools.js";
  27. import FollowDetail from './followDetail.jsx'
  28. import ShowModalDiv from "@/showModal.jsx";
  29. import ZhuanjiaoDetail from "@/zhuanjiaoDetail.jsx";
  30. import IntentionDetail from './intentionDetail/intentionDetail.jsx'
  31. import './customer.less';
  32. import {ChooseList} from "../../../order/orderNew/chooseList";
  33. const {TabPane} = Tabs
  34. const IntentionCustomer = Form.create()(React.createClass({
  35. loadData(pageNo, apiUrl) {
  36. this.setState({
  37. visitModul:false,
  38. loading: true,
  39. ispage:pageNo,
  40. modalVisible:false
  41. });
  42. let api=apiUrl?apiUrl:this.props.ApiUrl;
  43. $.ajax({
  44. method: "post",
  45. dataType: "json",
  46. crossDomain: false,
  47. url: globalConfig.context + api,
  48. data: {
  49. pageNo: pageNo || 1,
  50. pageSize: this.state.pagination.pageSize,
  51. name: this.state.nameSearch,
  52. province: !(this.state.addressSearch).length ? this.state.provinceSearch : this.state.addressSearch[0],
  53. city: !(this.state.addressSearch).length ? '' : this.state.addressSearch[1],
  54. startDate: this.state.releaseDate[0],
  55. endDate: this.state.releaseDate[1],
  56. },
  57. success: function(data) {
  58. ShowModal(this);
  59. let theArr = [];
  60. if(data.error.length || data.data.list == "") {
  61. if(data.error && data.error.length) {
  62. message.warning(data.error[0].message);
  63. };
  64. } else {
  65. for(let i = 0; i < data.data.list.length; i++) {
  66. let thisdata = data.data.list[i];
  67. let diqu=(thisdata.province==null?"":thisdata.province)+(thisdata.city==null?"":"-"+thisdata.city)+(thisdata.area==null?"":"-"+thisdata.area);
  68. thisdata.key = i;
  69. thisdata.id = thisdata.uid;
  70. thisdata.transferTime = thisdata.transferTime && thisdata.transferTime.split(" ")[0];
  71. thisdata.lastSignTime = thisdata.lastSignTime && thisdata.lastSignTime.split(" ")[0];
  72. thisdata.lastFollowTime = thisdata.lastFollowTime && thisdata.lastFollowTime.split(" ")[0];
  73. locationProvince : diqu
  74. theArr.push(thisdata);
  75. };
  76. this.state.pagination.current = data.data.pageNo;
  77. this.state.pagination.total = data.data.totalCount;
  78. };
  79. if(data.data&&data.data.list&&!data.data.list.length){
  80. this.state.pagination.current=0
  81. this.state.pagination.total=0
  82. };
  83. this.setState({
  84. dataSource: theArr,
  85. pagination: this.state.pagination,
  86. selectedRowKeys:[]
  87. });
  88. }.bind(this),
  89. }).always(function() {
  90. this.setState({
  91. loading: false
  92. });
  93. }.bind(this));
  94. },
  95. getInitialState() {
  96. return {
  97. addressSearch: [],
  98. orgCodeUrl: [],
  99. companyLogoUrl: [],
  100. visible: false,
  101. searchMore: true,
  102. releaseDate: [],
  103. visitModul: false,
  104. keys: false,
  105. detailApi: "",
  106. followData: {},
  107. selectedRowKeys: [],
  108. selectedRowKey: [],
  109. selectedRows: [],
  110. loading: false,
  111. defaultActiveKey: '',
  112. modalVisible: false,
  113. pagination: {
  114. defaultCurrent: 1,
  115. defaultPageSize: 10,
  116. showQuickJumper: true,
  117. pageSize: 10,
  118. onChange: function (page) {
  119. this.loadData(page);
  120. }.bind(this),
  121. showTotal: function (total) {
  122. return "共" + total + "条数据";
  123. },
  124. },
  125. columns: [
  126. {
  127. title: "客户名称",
  128. dataIndex: "name",
  129. key: "name",
  130. },
  131. {
  132. title: "地区",
  133. dataIndex: "locationProvince",
  134. key: "locationProvince",
  135. },
  136. {
  137. title: "最新签单日期",
  138. dataIndex: "transferTime",
  139. key: "transferTime",
  140. },
  141. // {
  142. // title: "最新跟进日期",
  143. // dataIndex: "lastFollowTime",
  144. // key: "lastFollowTime",
  145. // },
  146. // {
  147. // title: "剩余私有天数",
  148. // dataIndex: "surplusFollowTime",
  149. // key: "surplusFollowTime",
  150. // },
  151. // {
  152. // title: "剩余签单天数",
  153. // dataIndex: "surplusSignTime",
  154. // key: "surplusSignTime",
  155. // },
  156. // {
  157. // title: "联系人",
  158. // dataIndex: "contacts",
  159. // key: "contacts",
  160. // },
  161. // {
  162. // title: "联系电话",
  163. // dataIndex: "contactMobile",
  164. // key: "contactMobile",
  165. // },
  166. {
  167. title: "社会属性",
  168. dataIndex: "societyTag",
  169. key: "societyTag",
  170. render: (text) => {
  171. return getSocialAttribute(text);
  172. },
  173. },
  174. {
  175. title: "操作",
  176. dataIndex: "abc",
  177. key: "abc",
  178. render: (text, record, index) => {
  179. return (
  180. <div>
  181. <Button
  182. onClick={(e) => {
  183. e.stopPropagation(), this.visit(record);
  184. }}
  185. type="primary"
  186. >
  187. 客户跟进
  188. </Button>
  189. <Button
  190. style={{ marginLeft: 10 }}
  191. onClick={(e) => {
  192. e.stopPropagation(), this.zhuanjiaoDetail(record);
  193. }}
  194. type="primary"
  195. >
  196. 转交记录
  197. </Button>
  198. </div>
  199. );
  200. },
  201. },
  202. ],
  203. data: [],
  204. dataSource: [],
  205. };
  206. },
  207. zhuanjiaoDetail(record) {
  208. this.setState({
  209. zhuanjiaoVisible: true,
  210. zhuanjiaoId: record.id
  211. })
  212. },
  213. zhuanjiaoDetailCancel() {
  214. this.setState({
  215. zhuanjiaoVisible: false
  216. })
  217. },
  218. //进入新增拜访记录
  219. visit(e) {
  220. this.setState({
  221. followData:e,
  222. visitModul:true,
  223. modalVisible:false
  224. })
  225. },
  226. //列表删除功能
  227. delectRow() {
  228. let deletedIds;
  229. for(let idx = 0; idx < this.state.selectedRows.length; idx++) {
  230. let rowItem = this.state.selectedRows[idx];
  231. if(rowItem.id) {
  232. deletedIds = rowItem.id;
  233. };
  234. };
  235. this.setState({
  236. loading: true,
  237. selectedRowKeys: [],
  238. });
  239. $.ajax({
  240. method: "get",
  241. dataType: "json",
  242. crossDomain: false,
  243. url: globalConfig.context + "/api/admin/customer/deleteCustomer",
  244. data: {
  245. uid: deletedIds, //删除的ID
  246. }
  247. }).done(function(data) {
  248. if(!data.error.length) {
  249. message.success('删除成功!');
  250. this.setState({
  251. loading: false,
  252. });
  253. } else {
  254. message.warning(data.error[0].message);
  255. };
  256. this.loadData(this.state.ispage);
  257. }.bind(this));
  258. },
  259. componentWillMount() {
  260. //城市
  261. let Province = [];
  262. provinceList.map(function(item) {
  263. var id = String(item.id)
  264. Province.push(
  265. <Select.Option value={id} key={item.name}>{item.name}</Select.Option>
  266. )
  267. });
  268. //行业
  269. let intentionalArr = [];
  270. industry.map(function(item) {
  271. intentionalArr.push(
  272. <Select.Option value={item.value} key={item.key}>{item.key}</Select.Option>
  273. )
  274. });
  275. this.state.Provinces = Province;
  276. this.state.intentionalOption = intentionalArr;
  277. this.loadData();
  278. },
  279. closeDesc(e, s) {
  280. this.state.basicState=e
  281. this.state.visitModul=e;
  282. this.state.modalVisible=e;
  283. this.state.showDesc = e;
  284. this.setState({
  285. defaultActiveKey:''
  286. })
  287. if(s) {
  288. this.loadData(this.state.ispage);
  289. };
  290. },
  291. search() {
  292. this.loadData();
  293. },
  294. reset() {
  295. this.state.nameSearch = '';
  296. this.state.addressSearch = [];
  297. this.state.provinceSearch = undefined;
  298. this.state.citySearch = undefined;
  299. this.state.releaseDate[0] = undefined;
  300. this.state.releaseDate[1] = undefined;
  301. this.loadData();
  302. },
  303. searchSwitch() {
  304. this.setState({
  305. visitModul:false,
  306. searchMore: !this.state.searchMore
  307. });
  308. },
  309. //整行点击
  310. tableRowClick(record) {
  311. this.state.visitModul=false;
  312. this.state.RowData = record;
  313. this.setState({
  314. // selectedRowKeys: [],
  315. modalVisible:true,
  316. basicState:true,
  317. contactState:true,
  318. modalName: record.name
  319. })
  320. },
  321. //指定转交人自动补全
  322. supervisor(e){
  323. $.ajax({
  324. method: "get",
  325. dataType: "json",
  326. crossDomain: false,
  327. url: globalConfig.context + "/api/admin/customer/listAdminByName",
  328. data:{
  329. adminName:e
  330. },
  331. success: function (data) {
  332. let thedata=data.data;
  333. if (!thedata) {
  334. if (data.error && data.error.length) {
  335. message.warning(data.error[0].message);
  336. };
  337. thedata = {};
  338. };
  339. this.setState({
  340. customerArr:thedata,
  341. });
  342. }.bind(this),
  343. }).always(function () {
  344. this.setState({
  345. loading: false
  346. });
  347. }.bind(this));
  348. },
  349. componentWillReceiveProps(nextProps) {
  350. if(nextProps.ApiUrl!=this.props.ApiUrl) {
  351. if(!this.state.searchMore){
  352. this.state.searchMore=true
  353. }
  354. this.state.nameSearch = '';
  355. this.state.addressSearch = [];
  356. this.state.provinceSearch = undefined;
  357. this.state.citySearch = undefined;
  358. this.state.releaseDate[0] = undefined;
  359. this.state.releaseDate[1] = undefined;
  360. this.loadData(null,nextProps.ApiUrl);
  361. };
  362. },
  363. changeList(arr) {
  364. const newArr = [];
  365. this.state.columns.forEach(item => {
  366. arr.forEach(val => {
  367. if (val === item.title) {
  368. newArr.push(item);
  369. }
  370. });
  371. });
  372. this.setState({
  373. changeList: newArr
  374. });
  375. },
  376. //上级主管输入框失去焦点是判断客户是否存在
  377. selectAuto(value, options) {
  378. this.setState({
  379. auto: value,
  380. });
  381. },
  382. //值改变时请求客户名称
  383. httpChange(e) {
  384. if (e.length >= 1) {
  385. this.supervisor(e);
  386. }
  387. this.setState({
  388. auto: e,
  389. });
  390. },
  391. showConfirm(fn, record) {
  392. Modal.confirm({
  393. title: "提示",
  394. content: (
  395. <span style={{ color: "red" }}>
  396. 确定要转交以下客户吗?
  397. {
  398. this.state.selectedRows.map((value,index)=>(
  399. <div key={index} style={{marginTop:'5px',color: "#000"}}>
  400. {value.name}
  401. </div>
  402. ))
  403. }
  404. </span>
  405. ),
  406. onOk() {
  407. fn(record);
  408. },
  409. onCancel() {},
  410. });
  411. },
  412. //转交
  413. changeAssigner() {
  414. if (this.state.theTypes) {
  415. let changeIds = '';
  416. let oldAid = '';
  417. for (let idx = 0; idx < this.state.selectedRows.length; idx++) {
  418. let rowItem = this.state.selectedRows[idx];
  419. if (rowItem.id) {
  420. oldAid = rowItem.aid;
  421. changeIds = this.state.selectedRows.length-1 === idx ? changeIds +rowItem.id : changeIds + rowItem.id + ',' ;
  422. }
  423. }
  424. $.ajax({
  425. method: "get",
  426. dataType: "json",
  427. crossDomain: false,
  428. url: globalConfig.context + "/api/admin/customer/transferToOther",
  429. data: {
  430. uid: changeIds, //这一行数据的ID
  431. aid: this.state.theTypes, //指定转交人的ID
  432. oldAid: oldAid,
  433. operatorType:4
  434. },
  435. }).done(
  436. function (data) {
  437. if (!data.error.length) {
  438. message.success("转交成功!");
  439. this.setState({
  440. auto: "",
  441. loading: false,
  442. selectedRowKeys: [],
  443. });
  444. } else {
  445. message.warning(data.error[0].message);
  446. }
  447. this.loadData(
  448. Math.min(
  449. this.state.ispage == undefined ? 1 : this.state.ispage,
  450. Math.ceil((this.state.pagination.total - 1) / 10)
  451. )
  452. );
  453. }.bind(this)
  454. );
  455. } else {
  456. message.warning("请输入转交人姓名");
  457. }
  458. },
  459. blurChange(e) {
  460. let theType = "";
  461. let contactLists = this.state.customerArr || [];
  462. if (e) {
  463. contactLists.map(function (item) {
  464. if (item.name == e.toString()) {
  465. theType = item.id;
  466. }
  467. });
  468. }
  469. this.setState({
  470. theTypes: theType,
  471. });
  472. },
  473. render() {
  474. const rowSelection = {
  475. selectedRowKeys: this.state.selectedRowKeys,
  476. onChange: (selectedRowKeys, selectedRows) => {
  477. this.setState({
  478. modalVisible:false,
  479. selectedRows: selectedRows.slice(-1),
  480. selectedRowKeys: selectedRowKeys.slice(-1)
  481. });
  482. },
  483. onSelect: (recordt, selected, selectedRows) => {
  484. this.setState({
  485. modalVisible:false,
  486. recordt: recordt.id
  487. })
  488. },
  489. };
  490. const hasSelected = this.state.selectedRowKeys.length > 0;
  491. const { RangePicker } = DatePicker;
  492. const dataSources=this.state.customerArr || [];
  493. const options = dataSources.map((group) =>
  494. <Select.Option key={group.id} value={group.name}>{group.name}</Select.Option>
  495. )
  496. const intentionState = this.props.intentionState ||'';
  497. return (
  498. <div className="user-content">
  499. <ShowModalDiv ShowModal={this.state.showModal} />
  500. {this.state.zhuanjiaoVisible ? (
  501. <ZhuanjiaoDetail
  502. cancel={this.zhuanjiaoDetailCancel}
  503. visible={this.state.zhuanjiaoVisible}
  504. type={1}
  505. id={this.state.zhuanjiaoId}
  506. />
  507. ) : (
  508. ""
  509. )}
  510. <div className="content-title">
  511. <span>{!intentionState ? "签单客户" : "签单客户"}</span>
  512. </div>
  513. <Tabs defaultActiveKey="1" className="test">
  514. <TabPane tab="搜索" key="1">
  515. <div className="user-search">
  516. <Input
  517. placeholder="客户名称"
  518. value={this.state.nameSearch}
  519. onChange={(e) => {
  520. this.setState({ nameSearch: e.target.value });
  521. }}
  522. />
  523. <Select
  524. placeholder="省"
  525. style={{ width: 80 }}
  526. value={this.state.provinceSearch}
  527. onChange={(e) => {
  528. this.setState({ provinceSearch: e });
  529. }}
  530. >
  531. {this.state.Provinces}
  532. </Select>
  533. <span style={{ marginRight: "10px" }}>
  534. <Cascader
  535. options={citySelect()}
  536. value={this.state.addressSearch}
  537. placeholder="选择城市"
  538. onChange={(e, pre) => {
  539. this.setState({ addressSearch: e });
  540. }}
  541. />
  542. </span>
  543. {/* <div className="clearfix" style={{ marginTop: "5px" }}>
  544. <div
  545. className="search-more"
  546. style={this.state.searchMore ? { display: "none" } : {}}
  547. > */}
  548. <span>签单时间:</span>
  549. <RangePicker
  550. value={[
  551. this.state.releaseDate[0]
  552. ? moment(this.state.releaseDate[0])
  553. : null,
  554. this.state.releaseDate[1]
  555. ? moment(this.state.releaseDate[1])
  556. : null,
  557. ]}
  558. onChange={(data, dataString) => {
  559. this.setState({ releaseDate: dataString });
  560. }}
  561. />
  562. {/* </div>
  563. </div> */}
  564. <Button
  565. type="primary"
  566. onClick={this.search}
  567. style={{ marginLeft: 10 }}
  568. >
  569. 搜索
  570. </Button>
  571. <Button onClick={this.reset}>重置</Button>
  572. {/* {adminData.isSuperAdmin?<Popconfirm title="是否删除?" onConfirm={this.delectRow} okText="是" cancelText="否">
  573. <Button type="danger" style={{marginLeft:'10px'}}
  574. disabled={!hasSelected}
  575. >删除<Icon type="minus" />
  576. </Button>
  577. </Popconfirm>:''
  578. }*/}
  579. {/* <span style={{ marginLeft: "10px", marginRight: "20px" }}>
  580. 更多搜索
  581. <Switch
  582. checked={!this.state.searchMore}
  583. onChange={this.searchSwitch}
  584. />
  585. </span> */}
  586. </div>
  587. </TabPane>
  588. <TabPane tab="操作" key="2">
  589. <div className="user-search">
  590. <AutoComplete
  591. className="certain-category-search"
  592. dropdownClassName="certain-category-search-dropdown"
  593. dropdownMatchSelectWidth={false}
  594. dropdownStyle={{ width: 120 }}
  595. style={{ width: "120px" }}
  596. dataSource={options}
  597. placeholder="输入转交人姓名"
  598. value={this.state.auto}
  599. onChange={this.httpChange}
  600. filterOption={true}
  601. onBlur={this.blurChange}
  602. onSelect={this.selectAuto}
  603. disabled={!hasSelected}
  604. >
  605. <Input />
  606. </AutoComplete>
  607. <Button
  608. type="primary"
  609. onClick={(e) => {
  610. e.stopPropagation();
  611. this.showConfirm(this.changeAssigner);
  612. }}
  613. disabled={!hasSelected}
  614. style={{ marginRight: 10 }}
  615. >
  616. 转交客户
  617. </Button>
  618. <Button
  619. disabled={this.state.selectedRows.length === 0}
  620. type="primary"
  621. onClick={()=>{
  622. this.setState({
  623. defaultActiveKey: '5'
  624. },()=>{
  625. this.tableRowClick(this.state.selectedRows[0]);
  626. })
  627. }}
  628. style={{float: 'right' }}
  629. >
  630. 转交业务
  631. </Button>
  632. </div>
  633. </TabPane>
  634. <TabPane tab="更改表格显示数据" key="3">
  635. <div style={{ marginLeft: 10 }}>
  636. <ChooseList
  637. columns={this.state.columns}
  638. changeFn={this.changeList}
  639. changeList={this.state.changeList}
  640. top={55}
  641. margin={11}
  642. />
  643. </div>
  644. </TabPane>
  645. </Tabs>
  646. <div className="patent-table">
  647. <Spin spinning={this.state.loading}>
  648. <Table
  649. size="middle"
  650. columns={
  651. this.state.changeList
  652. ? this.state.changeList
  653. : this.state.columns
  654. }
  655. dataSource={this.state.dataSource}
  656. rowSelection={rowSelection}
  657. pagination={this.state.pagination}
  658. onRowClick={this.tableRowClick}
  659. />
  660. </Spin>
  661. </div>
  662. <FollowDetail
  663. followData={this.state.followData}
  664. visitModul={this.state.visitModul}
  665. closeDesc={this.closeDesc}
  666. loadData={this.loadData}
  667. />
  668. <IntentionDetail
  669. detailApi={this.props.detailApi}
  670. IntentionData={this.state.RowData}
  671. loadData={this.loadData}
  672. modalVisible={this.state.modalVisible}
  673. defaultActiveKey={this.state.defaultActiveKey}
  674. name={this.state.modalName}
  675. closeDesc={this.closeDesc}
  676. basicState={this.state.basicState}
  677. contactState={this.state.contactState}
  678. />
  679. </div>
  680. );
  681. }
  682. }));
  683. export default IntentionCustomer;