index.jsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import { Input, Button, Spin, message, Popconfirm, Modal } from 'antd'
  2. import React, { useState, useEffect, useRef } from 'react'
  3. import styles from '@/pages/Customer/Company/components/ConnectCompany/index.less'
  4. import { SearchOutlined } from '@ant-design/icons'
  5. import { useDebounceFn } from 'ahooks'
  6. import { apiAddClient, apiChangeClient, queryClient } from '@/services/customer'
  7. import consts from '@/basic/consts'
  8. import { formatValues } from '@/components/LazyCascader'
  9. import AddClient from '../AddClient'
  10. const ConnectClient = ({
  11. onCancel,
  12. dataId,
  13. onSelect,
  14. preUrl = 'client',
  15. showFooter = true,
  16. otherParams = {},
  17. ...resetModalProps
  18. }) => {
  19. const scrollRef = useRef()
  20. const [state, setState] = useState({
  21. laoding: true,
  22. client: [],
  23. searchVal: '',
  24. noMore: false,
  25. current: 1,
  26. pageSize: 10,
  27. total: 0
  28. })
  29. const initData = async params => {
  30. const { data: { client, total } = { client: [], total: 0 }, code = -1 } = await queryClient({
  31. ...params,
  32. waiver: true
  33. })
  34. if (code === consts.RET_CODE.SUCCESS) {
  35. if (params?.current === 1) {
  36. scrollRef.current?.scrollTo({ top: 0 })
  37. // 请求的是第一页或者搜索框
  38. setState({ ...state, client, total, laoding: false, searchVal: params?.search })
  39. } else {
  40. setState({
  41. ...state,
  42. client: state.client.concat(client),
  43. total,
  44. searchVal: params?.search,
  45. laoding: false,
  46. current: params?.current || 1
  47. })
  48. }
  49. }
  50. }
  51. useEffect(() => {
  52. initData({ current: 1, pageSize: 10 })
  53. }, [])
  54. const onChange = e => {
  55. const { value = '' } = e.target || e.currentTarget
  56. initData({ search: value, current: 1, pageSize: state.pageSize })
  57. }
  58. const { run: handleInputChange } = useDebounceFn(onChange)
  59. const addConfirm = async values => {
  60. const payload = formatValues(values)
  61. const { code = -1, msg = '新增成功' } = await apiAddClient(payload)
  62. if (code === consts.RET_CODE.SUCCESS) {
  63. if (Object.hasOwnProperty.call(values, `${preUrl}Id`)) {
  64. message.success('新增成功并且绑定成功')
  65. onSelect(values.name)
  66. onCancel()
  67. } else {
  68. message.success(msg)
  69. initData()
  70. }
  71. }
  72. }
  73. // 商机/软件锁关联客户
  74. const connectClient = async clientId => {
  75. const { code = -1 } = await apiChangeClient(preUrl, { id: dataId, clientId, ...otherParams })
  76. if (code === consts.RET_CODE.SUCCESS) {
  77. // message.success('关联成功')
  78. onSelect()
  79. onCancel()
  80. }
  81. }
  82. const handleListScroll = () => {
  83. // 未滚动到底部
  84. if (
  85. scrollRef.current.scrollHeight - scrollRef.current.clientHeight <=
  86. scrollRef.current.scrollTop
  87. ) {
  88. // 已到底部
  89. if (state.current * state.pageSize > state.total) {
  90. setState({ ...state, noMore: true })
  91. return
  92. }
  93. state.current * state.pageSize < state.total &&
  94. initData({ current: state.current + 1, pageSize: state.pageSize, search: state.searchVal })
  95. }
  96. }
  97. return (
  98. <Modal
  99. {...resetModalProps}
  100. onCancel={onCancel}
  101. width="50vw"
  102. title={
  103. <Input
  104. prefix={<SearchOutlined />}
  105. className={styles.inputSearch}
  106. placeholder="输入客户名称搜索"
  107. onChange={handleInputChange}
  108. />
  109. }
  110. >
  111. <div
  112. className={styles.modalContent}
  113. ref={scrollRef}
  114. onScroll={handleListScroll}
  115. style={{ paddingBottom: 0 }}
  116. >
  117. <Spin spinning={state.laoding}>
  118. {state.client.map(item => (
  119. <div key={item.id} className={styles.card}>
  120. <span className="w-1/6">{item.clientName}</span>
  121. <span className="w-1/6">{item.position}</span>
  122. <span className="w-1/6">{item.telephone}</span>
  123. <span className="w-1/2 flex justify-between">
  124. <span>{item.companyName}</span>
  125. <Popconfirm
  126. title="确认选择ta"
  127. onConfirm={() => connectClient(item.id)}
  128. okText="确认"
  129. cancelText="取消"
  130. >
  131. <Button type="primary" size="small">
  132. 选择ta
  133. </Button>
  134. </Popconfirm>
  135. </span>
  136. </div>
  137. ))}
  138. </Spin>
  139. {state.noMore && <div className="text-center text-gray-400 my-4">已到底部</div>}
  140. </div>
  141. {showFooter ? (
  142. <div className={styles.modalFooter}>
  143. <AddClient
  144. onConfirm={addConfirm}
  145. dataId={dataId}
  146. dataType={preUrl}
  147. buttonProps={{ ghost: true }}
  148. btnTitle={'添加并关联到新客户'}
  149. />
  150. </div>
  151. ) : null}
  152. </Modal>
  153. )
  154. }
  155. export default ConnectClient