selectGroupLeader.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. import useNewToken from '@/Hook/useNewToken';
  2. import React, { useEffect, useState } from 'react';
  3. import { App, Button, Input, Modal, Select, Table, Tag, Tooltip, Typography } from 'antd';
  4. import { CloseCircleFilled, SearchOutlined } from '@ant-design/icons';
  5. import '../corpUserManage/global.less'
  6. import { useAjax } from '@/Hook/useAjax';
  7. import { getCorpUserChatListApi, getCorpUserChatListProps } from '../../API/groupLeaderManage';
  8. import { getAdAccountAllOfMember, getCorpAllListApi } from '@/API/global';
  9. import { STATUSENUM } from '.';
  10. interface SelectCorpUserChatUserProps {
  11. value?: { label: string, value: number, name: string, corpName: string, corpId: string, corpUserId: string }[];
  12. onChange?: (value: { label: string, value: number, name: string, corpName: string, corpId: string, corpUserId: string }[]) => void;
  13. placeholder?: React.ReactNode
  14. }
  15. /**
  16. * 选择群主
  17. * @returns
  18. */
  19. const SelectGroupLeader: React.FC<SelectCorpUserChatUserProps> = ({ value, onChange, placeholder, ...its }) => {
  20. /************************************************************/
  21. const { token } = useNewToken()
  22. const [visible, setVisible] = useState<boolean>(false);
  23. /************************************************************/
  24. return <>
  25. <div
  26. className='selectCorpUser'
  27. style={{
  28. border: `1px solid ${token.colorBorder}`,
  29. padding: `0px ${token.paddingXS}px`,
  30. borderRadius: token.borderRadius,
  31. height: token.controlHeight,
  32. }}
  33. onClick={() => setVisible(true)}
  34. >
  35. <div className='selectCorpUserContent'>
  36. {(value && value?.length > 0) ? <>
  37. <Tag
  38. closable
  39. onClick={(e) => e.stopPropagation()}
  40. onClose={(e) => {
  41. e.preventDefault();
  42. onChange(value?.filter(item => item.value !== value?.[0]?.value))
  43. }}
  44. >
  45. {value?.[0]?.label || value?.[0]?.value}
  46. </Tag>
  47. {value?.length > 1 && <Tooltip
  48. color="#FFF"
  49. title={<span style={{ color: '#000' }}>
  50. {value?.filter((_, index) => index !== 0)?.map((item) => <Tag
  51. key={item.value}
  52. closable
  53. onClick={(e) => e.stopPropagation()}
  54. onClose={(e) => {
  55. e.stopPropagation()
  56. onChange(value?.filter(item1 => item1.value !== item.value))
  57. }}
  58. >{item.label || item?.value}</Tag>)}</span>
  59. }
  60. >
  61. <Tag>+{value.length - 1} ...</Tag>
  62. </Tooltip>}
  63. </> : <span style={{ color: token.colorTextDisabled }}>{placeholder || '请选择群主号'}</span>}
  64. </div>
  65. {(value && value?.length > 0) && <div className='selectCorpUserIcon'>
  66. <CloseCircleFilled
  67. className='selectCorpUserIconClear'
  68. style={{ fontSize: token.fontSizeIcon, color: token.colorTextSecondary }}
  69. onClick={(e) => {
  70. e.stopPropagation()
  71. onChange?.([])
  72. }}
  73. />
  74. </div>}
  75. </div>
  76. {visible && <SelectCorpUserChatUserModal
  77. {...its}
  78. value={value}
  79. visible={visible}
  80. placeholder={placeholder}
  81. onClose={() => setVisible(false)}
  82. onChange={(values) => {
  83. onChange?.(values)
  84. setVisible(false)
  85. }}
  86. />}
  87. </>
  88. };
  89. interface SelectCorpUserChatUserModalProps extends SelectCorpUserChatUserProps {
  90. visible?: boolean
  91. onClose?: () => void
  92. }
  93. const SelectCorpUserChatUserModal: React.FC<SelectCorpUserChatUserModalProps> = React.memo(({ placeholder, visible, onClose, onChange, value }) => {
  94. /**********************************************/
  95. const [editSelectedRow, setEditSelectedRow] = useState<any[]>([])
  96. const { message } = App.useApp()
  97. const [queryParams, setQueryParams] = useState<getCorpUserChatListProps>({ pageNum: 1, pageSize: 20 })
  98. const [queryParamsNew, setQueryParamsNew] = useState<getCorpUserChatListProps>({ pageNum: 1, pageSize: 20 })
  99. const getCorpUserChatList = useAjax((params) => getCorpUserChatListApi(params))
  100. const allOfMember = useAjax(() => getAdAccountAllOfMember())
  101. const getCorpAllList = useAjax((params) => getCorpAllListApi(params))
  102. /**********************************************/
  103. useEffect(() => {
  104. allOfMember.run()
  105. getCorpAllList.run({})
  106. }, [])
  107. useEffect(() => {
  108. getCorpUserChatList.run(queryParamsNew)
  109. }, [queryParamsNew])
  110. useEffect(() => {
  111. if (visible) {
  112. setEditSelectedRow(value?.length ? value.map(item => ({
  113. id: item.value,
  114. name: item.name,
  115. corpName: item.corpName,
  116. corpId: item.corpId,
  117. corpUserId: item.corpUserId
  118. })) : [])
  119. }
  120. }, [visible, value])
  121. const handleOk = () => {
  122. if (editSelectedRow.length) {
  123. onChange?.(editSelectedRow.map(item => ({
  124. label: `${item.name}(${item.corpName})`,
  125. value: item.id,
  126. name: item.name,
  127. corpName: item.corpName,
  128. corpId: item.corpId,
  129. corpUserId: item.corpUserId
  130. })))
  131. } else {
  132. message.error('请至少选择一条数据')
  133. }
  134. }
  135. return <Modal
  136. title={<strong>{placeholder}</strong>}
  137. open={visible}
  138. width={900}
  139. onCancel={onClose}
  140. onOk={handleOk}
  141. >
  142. <div className='selectCorpUserBody' style={{ width: '100%' }}>
  143. <div className='selectCorpUserBody_search'>
  144. <Select
  145. value={queryParams?.corpIds}
  146. onChange={(e) => setQueryParams({ ...queryParams, corpIds: e })}
  147. showSearch
  148. mode='multiple'
  149. style={{ minWidth: 110 }}
  150. maxTagCount={1}
  151. placeholder="主体"
  152. filterOption={(input, option) =>
  153. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  154. }
  155. allowClear
  156. options={getCorpAllList?.data?.data?.map((item: any) => ({ label: item.corpName, value: item.corpId }))}
  157. />
  158. <Input style={{ width: 150 }} onChange={(e) => setQueryParams({ ...queryParams, corpUserName: e.target.value as any })} value={queryParams?.corpUserName} placeholder="客服号名称" allowClear />
  159. <Input style={{ width: 150 }} onChange={(e) => setQueryParams({ ...queryParams, corpUserIds: e.target.value as any })} value={queryParams?.corpUserIds} placeholder="客服ID(多个,,空格换行)" allowClear />
  160. <Select
  161. value={queryParams?.operUserId}
  162. onChange={(e) => setQueryParams({ ...queryParams, operUserId: e })}
  163. showSearch
  164. style={{ width: 110 }}
  165. placeholder="运营"
  166. filterOption={(input, option) =>
  167. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  168. }
  169. allowClear
  170. options={allOfMember?.data?.data?.map((item: any) => ({ label: item.nickname, value: item.userId }))}
  171. />
  172. <Select
  173. value={queryParams?.putUserId}
  174. onChange={(e) => setQueryParams({ ...queryParams, putUserId: e })}
  175. showSearch
  176. style={{ width: 110 }}
  177. placeholder="投手"
  178. filterOption={(input, option) =>
  179. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  180. }
  181. allowClear
  182. options={allOfMember?.data?.data?.map((item: any) => ({ label: item.nickname, value: item.userId }))}
  183. />
  184. <Select
  185. style={{ width: 90 }}
  186. showSearch
  187. placeholder="状态"
  188. value={queryParams?.status}
  189. onChange={(value) => setQueryParams({ ...queryParams, status: value })}
  190. filterOption={(input, option) =>
  191. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  192. }
  193. allowClear
  194. options={[{ label: '已激活', value: 1 }, { label: '已禁用', value: 2 }, { label: '未激活', value: 4 }, { label: '退出企业', value: 5 }]}
  195. />
  196. <Button type="primary" onClick={() => {
  197. setQueryParamsNew({ ...queryParams, pageNum: 1 })
  198. }} loading={getCorpUserChatList.loading} icon={<SearchOutlined />}>搜索</Button>
  199. </div>
  200. <div className='selectCorpUserBody_content'>
  201. <Table
  202. columns={[
  203. {
  204. title: '群主主体',
  205. dataIndex: 'corpName',
  206. key: 'corpName',
  207. align: 'center',
  208. width: 70,
  209. ellipsis: true,
  210. },
  211. {
  212. title: '群主企微主体ID',
  213. dataIndex: 'corpId',
  214. key: 'corpId',
  215. align: 'center',
  216. width: 70,
  217. ellipsis: true,
  218. },
  219. {
  220. title: '群主企微号',
  221. dataIndex: 'name',
  222. key: 'name',
  223. align: 'center',
  224. width: 70,
  225. ellipsis: true,
  226. },
  227. {
  228. title: '群主企微号ID',
  229. dataIndex: 'corpUserId',
  230. key: 'corpUserId',
  231. align: 'center',
  232. width: 70,
  233. ellipsis: true,
  234. },
  235. {
  236. title: '主运营',
  237. dataIndex: 'operUser',
  238. key: 'operUser',
  239. align: 'center',
  240. width: 70,
  241. ellipsis: true,
  242. render: (value) => {
  243. return value?.nickname || '--'
  244. }
  245. },
  246. {
  247. title: '投手',
  248. dataIndex: 'putUser',
  249. key: 'putUser',
  250. align: 'center',
  251. width: 70,
  252. ellipsis: true,
  253. render: (value) => {
  254. return value?.nickname || '--'
  255. }
  256. },
  257. {
  258. title: '运营助理',
  259. dataIndex: 'userList',
  260. key: 'userList',
  261. width: 120,
  262. ellipsis: true,
  263. render: (value) => {
  264. return value?.map(item => item.nickname)?.join('、') || '--'
  265. }
  266. },
  267. {
  268. title: '状态',
  269. dataIndex: 'status',
  270. key: 'status',
  271. width: 70,
  272. align: 'center',
  273. render: (value) => {
  274. return STATUSENUM[value]
  275. }
  276. }
  277. ]}
  278. dataSource={getCorpUserChatList?.data?.data?.records}
  279. scroll={{ y: 350 }}
  280. rowKey={'id'}
  281. size='small'
  282. loading={getCorpUserChatList?.loading}
  283. pagination={{
  284. total: getCorpUserChatList?.data?.data?.total,
  285. showTotal: (total) => `共 ${total} 条数据`,
  286. showQuickJumper: true,
  287. showSizeChanger: true,
  288. pageSizeOptions: ['10', '20', '50', '100'],
  289. onChange: (pageNum, pageSize) => {
  290. setQueryParams({ ...queryParams, pageNum, pageSize })
  291. setQueryParamsNew({ ...queryParamsNew, pageNum, pageSize })
  292. }
  293. }}
  294. rowSelection={{
  295. type: 'checkbox',
  296. selectedRowKeys: editSelectedRow?.map(item => item.id),
  297. onSelect: (record, selected: any) => {
  298. if (selected) {
  299. setEditSelectedRow([...editSelectedRow, record])
  300. } else {
  301. setEditSelectedRow(editSelectedRow?.filter(item => item.id !== record.id))
  302. }
  303. },
  304. onSelectAll: (selected: any, rows: any, changeRows: any[]) => {
  305. if (selected) {
  306. setEditSelectedRow([...editSelectedRow, ...changeRows])
  307. } else {
  308. let newArr = editSelectedRow?.filter(item => changeRows.every(i => i?.id !== item?.id))
  309. setEditSelectedRow(newArr)
  310. }
  311. }
  312. }}
  313. />
  314. </div>
  315. </div>
  316. </Modal>
  317. });
  318. export default SelectGroupLeader;