index.jsx 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. import React, { useState, useEffect } from 'react';
  2. import {
  3. Form,
  4. Icon,
  5. Input,
  6. Button,
  7. DatePicker,
  8. Select,
  9. Card,
  10. Row,
  11. Col,
  12. Popconfirm,
  13. Alert,
  14. Table,
  15. Avatar,
  16. notification,
  17. Modal,
  18. message,
  19. } from 'antd';
  20. import moment from 'moment';
  21. import request from '../../../utils/request';
  22. import apis from '../../../services/apis';
  23. import Styles from './style.less';
  24. import { router } from 'umi';
  25. import AuthButton from '@/components/AuthButton';
  26. import ChannelSelect from '@/components/SelectButton/channelSelect';
  27. const { Option } = Select;
  28. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  29. const { Meta } = Card;
  30. /**
  31. * 推荐客户
  32. */
  33. class ModalTable extends React.Component {
  34. constructor(props) {
  35. super(props);
  36. this.state = {
  37. dataSource: { records: [] },
  38. visibleData: { visible: false, customerId: '', realtyConsultant: '' },
  39. };
  40. }
  41. // 挂载之后
  42. componentDidMount() {
  43. this.getList({ pageNumber: 1, pageSize: 5 });
  44. }
  45. componentDidUpdate(preProps, preState) {
  46. if (this.props.visibleData.customerId !== preState.visibleData.customerId) {
  47. this.getList({ pageNumber: 1, pageSize: 5 });
  48. this.setState({ visibleData: this.props.visibleData });
  49. }
  50. }
  51. // 弹框确定按钮
  52. // eslint-disable-next-line react/sort-comp
  53. handleOk() {
  54. this.setState({ visibleData: { visible: false, customerId: '', realtyConsultant: '' } });
  55. }
  56. // 弹框取消按钮
  57. handleCancel() {
  58. this.setState({ visibleData: { visible: false, customerId: '', realtyConsultant: '' } });
  59. this.props.onCancel();
  60. }
  61. getList(params) {
  62. // eslint-disable-next-line no-console
  63. console.log('this.state.visibleData', this.state.visibleData);
  64. const { customerId } = this.state.visibleData;
  65. if (customerId === '' || customerId === undefined) {
  66. return;
  67. }
  68. // 网路请求
  69. // 网路请求
  70. request({ ...apis.customer.recommend, urlData: { id: customerId }, params: { ...params } })
  71. .then(res => {
  72. this.setState({ dataSource: res });
  73. })
  74. .catch(err => {
  75. // eslint-disable-next-line no-unused-expressions
  76. <Alert
  77. style={{
  78. marginBottom: 24,
  79. }}
  80. message={err}
  81. type="error"
  82. showIcon
  83. />;
  84. });
  85. }
  86. // 分页
  87. onChange(pageNum) {
  88. this.getList({ pageNumber: pageNum, pageSize: 5 });
  89. }
  90. render() {
  91. const columns = [
  92. {
  93. title: '头像',
  94. // eslint-disable-next-line jsx-a11y/alt-text
  95. render: (text, record) => (
  96. <Avatar shape="square" src={record.picture} size={64} icon="user" />
  97. ),
  98. // render: (text, records) => <img src={records.picture} width={50} height={50} />,
  99. },
  100. {
  101. title: '用户名',
  102. dataIndex: 'name',
  103. key: 'name',
  104. // render: (row) => <><span>{console.log(row, 'row')}{row.name || row.nickname}</span></>,
  105. },
  106. {
  107. title: '电话',
  108. dataIndex: 'phone',
  109. key: 'phone',
  110. },
  111. {
  112. title: '性别',
  113. dataIndex: 'sex',
  114. key: 'sex',
  115. render: (text, records) => <span>{records.sex === 1 ? '男' : '女'}</span>,
  116. },
  117. {
  118. title: '意向项目',
  119. dataIndex: 'intention',
  120. key: 'intention',
  121. },
  122. {
  123. title: '推荐时间',
  124. dataIndex: 'createDate',
  125. key: 'createDate',
  126. render: (_, record) => (
  127. <>
  128. <span>
  129. {record.createDate && moment(record.createDate).format('YYYY-MM-DD HH:mm:ss')}
  130. </span>
  131. </>
  132. ),
  133. },
  134. {
  135. title: '状态',
  136. // eslint-disable-next-line consistent-return
  137. render: (text, records) => {
  138. if (records.status === 1) {
  139. return '报备';
  140. }
  141. if (records.status === 2) {
  142. return '到访';
  143. }
  144. if (records.status === 3) {
  145. return '认筹';
  146. }
  147. if (records.status === 4) {
  148. return '签约';
  149. }
  150. if (records.status === 5) {
  151. return '结佣';
  152. }
  153. // if (records.status === 6) {
  154. // return '报废';
  155. // }
  156. },
  157. },
  158. ];
  159. return (
  160. <>
  161. <Modal
  162. title="推荐客户"
  163. destroyOnClose="true"
  164. width={900}
  165. footer={null}
  166. visible={this.state.visibleData.visible}
  167. // onOk={() => this.handleOk()}
  168. onCancel={e => this.handleCancel(e)}
  169. >
  170. <Table
  171. rowKey="independentList"
  172. dataSource={this.state.dataSource.records}
  173. columns={columns}
  174. pagination={{
  175. current: this.state.dataSource.current,
  176. pageSize: this.state.dataSource.size,
  177. total: this.state.dataSource.total,
  178. onChange: e => this.onChange(e),
  179. }}
  180. />
  181. </Modal>
  182. </>
  183. );
  184. }
  185. }
  186. // defaultCurrent={1} total={dataSource.total} pageSize={6} onChange={onChange} current={dataSource.current}
  187. /**
  188. * 邀请客户
  189. */
  190. class InviteTable extends React.Component {
  191. constructor(props) {
  192. super(props);
  193. this.state = {
  194. dataSource: { records: [] },
  195. visibleData: { visible: false, customerId: '', realtyConsultant: '' },
  196. };
  197. }
  198. // 挂载之后
  199. componentDidMount() {}
  200. componentDidUpdate(preProps, preState) {
  201. const { customerId } = this.props.visibleData;
  202. if (this.props.visibleData.visible !== preState.visibleData.visible) {
  203. this.getList({ id: customerId, pageNumber: 1, pageSize: 5 });
  204. this.setState({ visibleData: this.props.visibleData });
  205. }
  206. }
  207. // 弹框确定按钮
  208. // eslint-disable-next-line react/sort-comp
  209. handleOk() {
  210. this.setState({ dataSource: { records: [] } });
  211. this.props.onCancel();
  212. }
  213. // 弹框取消按钮
  214. handleCancel() {
  215. console.log('345');
  216. this.setState({ dataSource: { records: [] } });
  217. this.props.onCancel();
  218. }
  219. getList(params) {
  220. const { id } = params;
  221. console.log(id);
  222. if (id === '' || id === undefined) {
  223. return;
  224. }
  225. request({ ...apis.customer.InviteClientsList, params: { ...params } })
  226. .then(res => {
  227. this.setState({ dataSource: res });
  228. })
  229. .catch(err => {
  230. // eslint-disable-next-line no-unused-expressions
  231. });
  232. }
  233. // 分页
  234. onChange(pageNum) {
  235. this.getList({ pageNumber: pageNum, pageSize: 5 });
  236. }
  237. render() {
  238. const columns = [
  239. {
  240. title: '头像',
  241. dataIndex: 'img',
  242. key: 'img',
  243. align: 'center',
  244. render: (text, record) => <img src={record.avatarurl} width={50} height={50} />,
  245. },
  246. {
  247. title: '用户姓名',
  248. dataIndex: 'nickname',
  249. key: 'nickname',
  250. align: 'center',
  251. render: row => (
  252. <>
  253. <span>
  254. {console.log(row, 'row')}
  255. {row.name || row.nickname}
  256. </span>
  257. </>
  258. ),
  259. },
  260. {
  261. title: '电话',
  262. dataIndex: 'phone',
  263. key: 'phone',
  264. align: 'center',
  265. },
  266. {
  267. title: '性别',
  268. dataIndex: 'sex',
  269. key: 'sex',
  270. align: 'center',
  271. render: (text, list) => <span>{list.sex === 1 ? '男' : '女'}</span>,
  272. },
  273. ];
  274. return (
  275. <>
  276. <Modal
  277. title="邀请经纪人"
  278. destroyOnClose="true"
  279. width={900}
  280. footer={null}
  281. visible={this.state.visibleData.visible}
  282. // onOk={() => this.handleOk()}
  283. onCancel={e => this.handleCancel(e)}
  284. >
  285. <Table
  286. rowKey="independent"
  287. dataSource={this.state.dataSource.records}
  288. columns={columns}
  289. pagination={{ total: this.state.dataSource.total, onChange: e => this.onChange(e) }}
  290. />
  291. </Modal>
  292. </>
  293. );
  294. }
  295. }
  296. /**
  297. *
  298. *主题列表
  299. * @param {*} props
  300. * @returns
  301. */
  302. function body(props) {
  303. const { getFieldDecorator, getFieldsValue } = props.form;
  304. // eslint-disable-next-line react-hooks/rules-of-hooks
  305. const [dataSource, setDataSource] = useState({ records: [] });
  306. // eslint-disable-next-line react-hooks/rules-of-hooks
  307. useEffect(() => {
  308. getList({ pageNumber: 1, pageSize: 10 });
  309. }, []);
  310. function openNotificationWithIcon(type, message) {
  311. notification[type]({
  312. message,
  313. description: '',
  314. });
  315. }
  316. function getList(params) {
  317. // 网路请求
  318. request({ ...apis.customer.agents, params: { ...params } })
  319. .then(res => {
  320. setDataSource(res);
  321. })
  322. .catch(err => {
  323. openNotificationWithIcon('error', err);
  324. });
  325. }
  326. // 提交事件
  327. function handleSubmit(e) {
  328. e.preventDefault();
  329. props.form.validateFields((err, values) => {
  330. console.log(values)
  331. if (!err) {
  332. getList({ pageNum: 1, pageSize: 10, ...values });
  333. }
  334. });
  335. }
  336. // eslint-disable-next-line react-hooks/rules-of-hooks
  337. const [gVisibleData, setGVisibleData] = useState({
  338. visible: false,
  339. customerId: '',
  340. realtyConsultant: '',
  341. });
  342. // eslint-disable-next-line react-hooks/rules-of-hooks
  343. const [gInviteData, setGInviteData] = useState({
  344. visible: false,
  345. customerId: '',
  346. realtyConsultant: '',
  347. });
  348. // Change 事件
  349. function handleSelectChange(e) {
  350. // eslint-disable-next-line no-console
  351. console.log(e);
  352. }
  353. function gM(row) {
  354. setGVisibleData({
  355. visible: true,
  356. customerId: row.personId,
  357. realtyConsultant: row.realtyConsultant,
  358. });
  359. setGInviteData({ visible: false });
  360. }
  361. function Invite(row) {
  362. setGInviteData({
  363. visible: true,
  364. customerId: row.personId,
  365. realtyConsultant: row.realtyConsultant,
  366. });
  367. setGVisibleData({ visible: false });
  368. }
  369. // 分页
  370. function onChange(pageNum) {
  371. // eslint-disable-next-line react-hooks/rules-of-hooks
  372. getList({ pageNum: pageNum, pageSize: 10 });
  373. }
  374. /**
  375. * 重置搜索
  376. */
  377. function handleReset() {
  378. props.form.resetFields();
  379. getList({ pageNumber: 1, pageSize: 10 });
  380. }
  381. function toAudit(cuurentId) {
  382. router.push({
  383. pathname: '/customer/recommendCustomer/audit',
  384. query: {
  385. id: cuurentId,
  386. },
  387. });
  388. }
  389. function exportIndependen() {
  390. const fieldsValue = getFieldsValue();
  391. console.log('fieldsValue', fieldsValue);
  392. request({
  393. ...apis.customer.customerRecommendAgentsExport,
  394. responseType: 'blob',
  395. params: { ...fieldsValue },
  396. })
  397. .then(response => {
  398. download(response);
  399. })
  400. .catch(error => {});
  401. }
  402. function onDelete(row) {
  403. const fieldsValue = getFieldsValue();
  404. request({ ...apis.customer.deleteChannelPerson, urlData: { id: row.personId } })
  405. .then(response => {
  406. message.info('删除成功');
  407. getList({ pageNum: 1, pageSize: 10, ...fieldsValue });
  408. })
  409. .catch(error => {});
  410. }
  411. function download(data) {
  412. if (!data) {
  413. return;
  414. }
  415. const url = window.URL.createObjectURL(new Blob([data]));
  416. const link = document.createElement('a');
  417. link.style.display = 'none';
  418. link.href = url;
  419. link.setAttribute('download', '经纪人.xlsx');
  420. document.body.append(link);
  421. link.click();
  422. }
  423. const columns = [
  424. {
  425. title: '头像',
  426. dataIndex: 'avatarurl',
  427. key: 'avatarurl',
  428. render: (_, record) => <Avatar shape="square" src={record.avatarurl} size={64} icon="user" />,
  429. },
  430. {
  431. title: '姓名',
  432. dataIndex: 'name',
  433. key: 'name',
  434. render: (_, record) => (
  435. <>
  436. <span>{record.name || record.nickname}</span>
  437. </>
  438. ),
  439. },
  440. {
  441. title: '电话',
  442. dataIndex: 'phone',
  443. key: 'phone',
  444. },
  445. {
  446. title: '性别',
  447. dataIndex: 'gender',
  448. key: 'gender',
  449. // eslint-disable-next-line no-nested-ternary
  450. render: (_, record) => (
  451. <>
  452. <span>{record.gender === '1' ? '男' : record.gender === '2' ? '女' : '未知'}</span>
  453. </>
  454. ),
  455. },
  456. {
  457. title: '类型',
  458. dataIndex: 'personType',
  459. key: 'personType',
  460. render: (_, record) => (
  461. <>
  462. <span>{record.personType === 'channel agent' ? '专业经纪人' : '专业经纪人'}</span>
  463. </>
  464. ),
  465. },
  466. {
  467. title: '所属渠道',
  468. dataIndex: 'channelName',
  469. key: 'channelName',
  470. render: (_, record) => (
  471. <>
  472. <span>{record.channelName}</span>
  473. </>
  474. ),
  475. },
  476. {
  477. title: '操作',
  478. dataIndex: 'customerId',
  479. key: 'customerId',
  480. render: (_, record) => (
  481. <>
  482. {
  483. <>
  484. {/* <span style={{ color: 'rgba(239,39,58,1)' }}>查看详细</span> */}
  485. {/* <AuthButton name="admin.channel.InviteClientsList.get" noRight={null}>
  486. <a style={{ color: 'rgba(239,39,58,1)' }} onClick={() => Invite(record)}>邀请经纪人</a>
  487. </AuthButton> */}
  488. {/* &nbsp;&nbsp;&nbsp;&nbsp; */}
  489. <AuthButton name="channel.customer.list" noRight={null}>
  490. <Button type="link" onClick={() => gM(record)}>
  491. 推荐客户
  492. </Button>
  493. </AuthButton>
  494. <AuthButton name="channel.disable" noRight={null}>
  495. <Popconfirm title="确定要进行删除操作 ?" onConfirm={() => onDelete(record)}>
  496. <Button type="link">删除</Button>
  497. </Popconfirm>
  498. </AuthButton>
  499. </>
  500. }
  501. </>
  502. ),
  503. },
  504. ];
  505. // <div>
  506. // <span className={channels.selectName}>渠道名称</span>
  507. // <Select defaultValue="请选择" style={{ width: 180 }} onChange={handleChange}>
  508. // <option value="">全部</option>
  509. // {data.channelNmae.map(Item =>
  510. // <Option value={Item.channelId}> {Item.channelName} </Option>,
  511. // )}
  512. // {/* {listItems} */}
  513. // </Select>
  514. // </div>
  515. // <div ></div>
  516. return (
  517. <Card>
  518. <Form
  519. layout="inline"
  520. onSubmit={e => handleSubmit(e, props)}
  521. style={{ display: 'flex', alignItems: 'center', marginBottom: '20px' }}
  522. >
  523. <Form.Item>
  524. {getFieldDecorator('channelId')(
  525. <ChannelSelect />,
  526. // <Select defaultValue="渠道名称" style={{ width: 180 }} onChange={handleChange}>
  527. // <option value="">全部</option>
  528. // {data.channelNmae.map(Item =>
  529. // <Option value={Item.channelId}> {Item.channelName} </Option>,
  530. // )}
  531. // </Select>,
  532. )}
  533. </Form.Item>
  534. <Form.Item>
  535. {getFieldDecorator('name')(
  536. <Input
  537. prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
  538. placeholder="姓名"
  539. />,
  540. )}
  541. </Form.Item>
  542. <Form.Item>
  543. {getFieldDecorator('tel')(
  544. <Input
  545. prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
  546. placeholder="电话"
  547. />,
  548. )}
  549. </Form.Item>
  550. <Form.Item style={{ position: 'absolute', right: '38px' }}>
  551. {/* <AuthButton name="admin.major.search" noRight={null}> */}
  552. <Button type="primary" htmlType="submit">
  553. 搜索
  554. </Button>
  555. {/* </AuthButton> */}
  556. <Button style={{ marginLeft: 8 }} onClick={handleReset}>
  557. 重置
  558. </Button>
  559. </Form.Item>
  560. </Form>
  561. <AuthButton name="admin.major.import" noRight={null}>
  562. <Button
  563. type="primary"
  564. onClick={() => exportIndependen()}
  565. style={{ float: 'right', margin: '20px 0', zIndex: 1 }}
  566. >
  567. 导出
  568. </Button>
  569. </AuthButton>
  570. <Table
  571. rowKey="personId"
  572. dataSource={dataSource.records}
  573. columns={columns}
  574. pagination={{ total: dataSource.total, onChange }}
  575. />
  576. {/* 推荐客户 */}
  577. <ModalTable
  578. visibleData={gVisibleData}
  579. onCancel={() => setGVisibleData({ visible: false, customerId: '', realtyConsultant: '' })}
  580. />
  581. {/* 邀请经纪人 */}
  582. <InviteTable
  583. visibleData={gInviteData}
  584. onCancel={() => setGInviteData({ visible: false, customerId: '', realtyConsultant: '' })}
  585. />
  586. </Card>
  587. );
  588. }
  589. const WrappedBody = Form.create({ name: 'body' })(body);
  590. export default WrappedBody;