index.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. import { App, Button, Card, Input, Pagination, Select, Table, Tabs } from 'antd';
  2. import React, { useEffect, useRef, useState } from 'react';
  3. import { MenuUnfoldOutlined, MenuFoldOutlined, PlusOutlined, SearchOutlined, UsergroupAddOutlined } from '@ant-design/icons';
  4. import style from './index.less'
  5. import GroupLeft from './groupLeft';
  6. import TeamMembers from '@/components/Team/teamMembers';
  7. import { getAdAccountAllOfMember } from '../../API/global';
  8. import { useAjax } from '@/Hook/useAjax';
  9. import { delAccountToGroupApi, getCorpUserApi } from '../../API/corpUserManage';
  10. import SearchBox from '../../components/searchBox';
  11. import { WeTableConfig } from './tableConfig';
  12. import { useSize } from 'ahooks';
  13. import { getBindMpListApi } from '../../API/corpUserAssign';
  14. import SettingsGroup from './settingsGroup';
  15. /**
  16. * 企微号管理
  17. * @returns
  18. */
  19. const CorpUserManage: React.FC = () => {
  20. /***************************************************/
  21. const { message } = App.useApp();
  22. const ref = useRef<HTMLDivElement>(null)
  23. const size = useSize(ref)
  24. const [queryForm, setQueryForm] = useState<CORP_USER_ASSIGN_API.GetCorpUserProps>({ pageNum: 1, pageSize: 20 })
  25. const [queryFormNew, setQueryFormNew] = useState<CORP_USER_ASSIGN_API.GetCorpUserProps>({ pageNum: 1, pageSize: 20 })
  26. const [activeKey, setActiveKey] = useState<string>('1')
  27. const [showLeft, setShowLeft] = useState<boolean>(false)
  28. const [selectedRows, setselectedRows] = useState<any[]>([])
  29. const [settingsGroupData, setSettingsGroupData] = useState<{ visible?: boolean, type: 'add' | 'del', data: any[] }>();
  30. const allOfMember = useAjax(() => getAdAccountAllOfMember())
  31. const getBindMpList = useAjax(() => getBindMpListApi())
  32. const getCorpUser = useAjax((params) => getCorpUserApi(params))
  33. const delAccountToGroup = useAjax((params) => delAccountToGroupApi(params))
  34. /***************************************************/
  35. useEffect(() => {
  36. allOfMember.run()
  37. getBindMpList.run()
  38. }, [])
  39. useEffect(() => {
  40. const params = { ...queryForm }
  41. if (params?.corpIds) {
  42. params.corpIds = (params.corpIds as any).split(/[\s,,\n]/).filter((item: string) => item)
  43. } else {
  44. delete params?.corpIds
  45. }
  46. if (params?.corpUserIds) {
  47. params.corpUserIds = (params.corpUserIds as any).split(/[\s,,\n]/).filter((item: string) => item)
  48. } else {
  49. delete params?.corpUserIds
  50. }
  51. getCorpUser.run(params)
  52. }, [queryForm])
  53. const delHandle = (groupId: number, data: any) => {
  54. delAccountToGroup.run({ currGroupId: groupId, corpUserList: [{ corpId: data.corpId, corpUserId: data.corpUserId }] }).then(res => {
  55. message.success('移出成功')
  56. getCorpUser.refresh()
  57. })
  58. }
  59. return <div className={style.corpUserManage}>
  60. <Tabs
  61. tabBarStyle={{ marginBottom: 1 }}
  62. activeKey={activeKey}
  63. type="card"
  64. onChange={(activeKey) => {
  65. if (activeKey !== 'contract') {
  66. let newQueryForm = JSON.parse(JSON.stringify(queryForm))
  67. delete newQueryForm?.groupId
  68. delete newQueryForm?.putUserId
  69. setQueryForm(newQueryForm)
  70. setActiveKey(activeKey)
  71. } else {
  72. setShowLeft(!showLeft)
  73. }
  74. }}
  75. items={[{ label: '我的', key: '1' }, { label: '组员', key: '2' }, { label: showLeft ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />, key: 'contract' }]}
  76. />
  77. <div className={style.corpUserManage_bottom}>
  78. {!showLeft && activeKey === '1' && <GroupLeft
  79. onChange={(groupId) => {
  80. setQueryForm({ ...queryForm, groupId, pageNum: 1 })
  81. setQueryFormNew({ ...queryFormNew, groupId, pageNum: 1 })
  82. }} value={queryForm?.groupId} />}
  83. {!showLeft && activeKey === '2' && <TeamMembers
  84. allOfMember={allOfMember}
  85. onChange={(putUserId) => {
  86. setQueryForm({ ...queryForm, putUserId, pageNum: 1 })
  87. setQueryFormNew({ ...queryFormNew, putUserId, pageNum: 1 })
  88. }}
  89. value={queryForm?.putUserId}
  90. />}
  91. <Card className={style.corpUserList} styles={{ body: { padding: 0, display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' } }}>
  92. <SearchBox
  93. bodyPadding={`16px 16px 12px`}
  94. buttons={<>
  95. <Button type="primary" onClick={() => {
  96. setQueryForm({ ...queryFormNew, pageNum: 1 })
  97. }} loading={getCorpUser.loading} icon={<SearchOutlined />}>搜索</Button>
  98. <Button type="primary" disabled={selectedRows?.length === 0} onClick={() => { setSettingsGroupData({ visible: true, data: selectedRows, type: 'add' }) }} icon={<UsergroupAddOutlined />}>添加到分组</Button>
  99. <Button type="primary" danger disabled={selectedRows?.length === 0} onClick={() => { setSettingsGroupData({ visible: true, data: selectedRows, type: 'del' }) }} icon={<UsergroupAddOutlined />}>移除分组</Button>
  100. </>}
  101. >
  102. <>
  103. <Input onChange={(e) => setQueryFormNew({ ...queryFormNew, corpIds: e.target.value as any })} value={queryFormNew?.corpIds} placeholder="企微ID(多个,,空格换行)" allowClear />
  104. <Input onChange={(e) => setQueryFormNew({ ...queryFormNew, corpUserName: e.target.value as any })} value={queryFormNew?.corpUserName} placeholder="客服号名称" allowClear />
  105. <Input onChange={(e) => setQueryFormNew({ ...queryFormNew, corpUserIds: e.target.value as any })} value={queryFormNew?.corpUserIds} placeholder="客服ID(多个,,空格换行)" allowClear />
  106. <Select
  107. value={queryFormNew?.operUserId}
  108. onChange={(e) => setQueryFormNew({ ...queryFormNew, operUserId: e })}
  109. showSearch
  110. style={{ width: 110 }}
  111. placeholder="运营"
  112. filterOption={(input, option) =>
  113. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  114. }
  115. allowClear
  116. options={allOfMember?.data?.data?.map((item: any) => ({ label: item.nickname, value: item.userId }))}
  117. />
  118. <Select
  119. value={queryFormNew?.mpAccountId}
  120. onChange={(e) => setQueryFormNew({ ...queryFormNew, mpAccountId: e })}
  121. showSearch
  122. style={{ width: 110 }}
  123. placeholder="公众号"
  124. filterOption={(input, option) =>
  125. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  126. }
  127. allowClear
  128. options={getBindMpList?.data?.data?.map((item: any) => ({ label: item.name, value: item.id }))}
  129. />
  130. <Select
  131. value={queryFormNew?.groupOwner}
  132. onChange={(e) => setQueryFormNew({ ...queryFormNew, groupOwner: e })}
  133. showSearch
  134. style={{ width: 100 }}
  135. placeholder="是否群主号"
  136. filterOption={(input, option) =>
  137. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  138. }
  139. allowClear
  140. options={[{ label: '是', value: 1 }, { label: '否', value: 0 }]}
  141. />
  142. <Select
  143. value={queryFormNew?.machine}
  144. onChange={(e) => setQueryFormNew({ ...queryFormNew, machine: e })}
  145. showSearch
  146. style={{ width: 100 }}
  147. placeholder="是否机器号"
  148. filterOption={(input, option) =>
  149. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  150. }
  151. allowClear
  152. options={[{ label: '是', value: 1 }, { label: '否', value: 0 }]}
  153. />
  154. <Select
  155. value={queryFormNew?.status}
  156. onChange={(e) => setQueryFormNew({ ...queryFormNew, status: e })}
  157. showSearch
  158. style={{ width: 100 }}
  159. placeholder="状态"
  160. filterOption={(input, option) =>
  161. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  162. }
  163. allowClear
  164. options={[{ label: '可用', value: 1 }, { label: '禁用', value: 0 }]}
  165. />
  166. <Select
  167. value={queryFormNew?.stopUse}
  168. onChange={(e) => setQueryFormNew({ ...queryFormNew, stopUse: e })}
  169. showSearch
  170. style={{ width: 100 }}
  171. placeholder="是否停用"
  172. filterOption={(input, option) =>
  173. ((option?.label ?? '') as string).toLowerCase().includes(input.toLowerCase())
  174. }
  175. allowClear
  176. options={[{ label: '可用', value: false }, { label: '停用', value: true }]}
  177. />
  178. </>
  179. </SearchBox>
  180. <div className={style.corpUserList_table} ref={ref}>
  181. <Table
  182. dataSource={getCorpUser?.data?.data?.records}
  183. columns={WeTableConfig(activeKey, queryForm?.groupId, () => getCorpUser.refresh(), delHandle)}
  184. bordered
  185. pagination={false}
  186. rowKey={'id'}
  187. loading={getCorpUser?.loading}
  188. scroll={{ y: size?.height && ref.current ? size?.height - ref.current.querySelector('.ant-table-thead').clientHeight : 300 }}
  189. rowSelection={{
  190. selectedRowKeys: selectedRows?.map((item: any) => item?.id),
  191. onSelect: (record: { id: string }, selected: boolean) => {
  192. let newData = JSON.parse(JSON.stringify(selectedRows))
  193. if (selected) {
  194. newData.push({ ...record })
  195. } else {
  196. newData = newData.filter((item: { id: string }) => item.id !== record.id)
  197. }
  198. setselectedRows(newData)
  199. },
  200. onSelectAll: (selected: boolean, _: { id: string }[], changeRows: { id: string }[]) => {
  201. let newData = JSON.parse(JSON.stringify(selectedRows || '[]'))
  202. if (selected) {
  203. changeRows.forEach((item: { id: string }) => {
  204. const index = newData.findIndex((ite: { id: string }) => ite.id === item.id)
  205. if (index === -1) {
  206. newData.push(item)
  207. }
  208. })
  209. } else {
  210. const newSelectAccData = newData.filter((item: { id: string }) => {
  211. const index = changeRows.findIndex((ite: { id: string }) => ite.id === item.id)
  212. if (index !== -1) {
  213. return false
  214. } else {
  215. return true
  216. }
  217. })
  218. newData = newSelectAccData
  219. }
  220. setselectedRows(newData)
  221. }
  222. }}
  223. />
  224. </div>
  225. <div className={style.corpUserList_footer}>
  226. <Pagination
  227. size="small"
  228. total={getCorpUser?.data?.data?.total || 0}
  229. showSizeChanger
  230. showQuickJumper
  231. pageSize={getCorpUser?.data?.data?.size || 20}
  232. current={getCorpUser?.data?.data?.current || 1}
  233. onChange={(page: number, pageSize: number) => {
  234. // ref.current?.scrollTo({ top: 0 })
  235. setTimeout(() => {
  236. setQueryForm({ ...queryForm, pageNum: page, pageSize })
  237. setQueryFormNew({ ...queryFormNew, pageNum: page, pageSize })
  238. }, 50)
  239. }}
  240. showTotal={(total: number) => <span style={{ fontSize: 12 }}>共 {total} 条</span>}
  241. />
  242. </div>
  243. </Card>
  244. </div>
  245. {/* 设置分组 */}
  246. {settingsGroupData?.visible && <SettingsGroup
  247. {...settingsGroupData}
  248. onClose={() => setSettingsGroupData(undefined)}
  249. onChange={() => {
  250. getCorpUser.refresh();
  251. setSettingsGroupData(undefined)
  252. setselectedRows([])
  253. }}
  254. />}
  255. </div>
  256. };
  257. export default CorpUserManage;