settingsEnterprise.tsx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import { Modal, Spin, Typography } from 'antd';
  2. import React, { useEffect, useState } from 'react';
  3. import '../../tencentAdPutIn/index.less';
  4. import './index.less';
  5. import { getCorpDepartmentListApi, getWechatPagesCsgroupUserApi, updateCustomerServiceGroupApi } from '@/services/adqV3/global';
  6. import { CloseOutlined, UserOutlined } from '@ant-design/icons';
  7. import { useAjax } from '@/Hook/useAjax';
  8. import { DataNode } from 'antd/lib/tree';
  9. import NTree from './nTree';
  10. interface IProps {
  11. adAccountId: number;
  12. data: {
  13. corpName: string;
  14. tencentCorpId: string;
  15. groupId: number;
  16. groupName: string;
  17. userInfoList: { userId: string, userName: string, msg: string, state: 0 | 1 }[]
  18. };
  19. visible: boolean;
  20. onClose?: () => void;
  21. onChange?: () => void;
  22. }
  23. // 定义接口
  24. interface Department {
  25. corpId: string;
  26. departmentId: number;
  27. name: string;
  28. parentid: number;
  29. orderIn: number;
  30. createTime: string;
  31. children: Department[];
  32. }
  33. const updateTreeData = (list: DataNode[], key: React.Key, children: DataNode[], childrenLen?: number): DataNode[] => list.map(node => {
  34. if (node.key === key) {
  35. if (childrenLen && node?.children) {
  36. return { ...node, children: [...node.children, ...children,] };
  37. }
  38. return {
  39. ...node,
  40. children,
  41. };
  42. }
  43. if (node.children) {
  44. return {
  45. ...node,
  46. children: updateTreeData(node.children, key, children, childrenLen),
  47. };
  48. }
  49. return node;
  50. });
  51. /**
  52. * 初始化数据
  53. * @param data
  54. * @returns
  55. */
  56. const getInitializationData = (data: Department[]): DataNode[] => {
  57. return data.map((item: Department) => {
  58. return { title: item.name, key: item.departmentId, checkable: false, children: item?.children?.length ? getInitializationData(item.children) : [] }
  59. })
  60. }
  61. /**
  62. * 修改客服组
  63. * @returns
  64. */
  65. const SettingsEnterprise: React.FC<IProps> = ({ adAccountId, data, visible, onClose, onChange }) => {
  66. /*********************************/
  67. const [treeData, setTreeData] = useState<DataNode[]>([]);
  68. const [loading, setLoading] = useState<boolean>(false);
  69. const [userInfoList, setUserInfoList] = useState<{ userId: string, userName: string, state?: 0 | 1, msg?: string }[]>(data.userInfoList || [])
  70. const getCorpDepartmentList = useAjax((params) => getCorpDepartmentListApi(params))
  71. const updateCustomerServiceGroup = useAjax((params) => updateCustomerServiceGroupApi(params))
  72. /*********************************/
  73. useEffect(() => {
  74. const getData = async () => {
  75. try {
  76. const res = await getCorpDepartmentList.run({ corpName: data.corpName })
  77. let dataTree: DataNode[] = []
  78. if (res?.length > 0) {
  79. dataTree = getInitializationData(res)
  80. }
  81. setLoading(true)
  82. const list = await getWechatPagesCsgroupUserApi({
  83. adAccountId,
  84. tencentCorpId: data.tencentCorpId,
  85. corpName: data.corpName
  86. })
  87. if (list.data?.length) {
  88. dataTree.push(...list.data.map((item: any) => ({ title: item.userName, key: item.userId, isLeaf: true })))
  89. }
  90. setLoading(false)
  91. setTreeData(dataTree)
  92. } catch (error) {
  93. console.error(error)
  94. }
  95. }
  96. if (adAccountId)
  97. getData()
  98. }, [adAccountId])
  99. const handleOk = () => {
  100. updateCustomerServiceGroup.run({
  101. adAccountId,
  102. tencentCorpId: data.tencentCorpId,
  103. groupId: data.groupId,
  104. groupName: data.groupName,
  105. userIdList: userInfoList.map(item => item.userId)
  106. }).then((res) => {
  107. if (res) {
  108. onChange?.()
  109. }
  110. })
  111. }
  112. const onLoadData = ({ key, children }: any) => {
  113. return new Promise<void>(resolve => {
  114. getWechatPagesCsgroupUserApi({
  115. adAccountId,
  116. tencentCorpId: data.tencentCorpId,
  117. corpName: data.corpName,
  118. departmentId: key
  119. }).then((res) => {
  120. setTreeData(origin =>
  121. updateTreeData(origin, key, res.data.map((item: any) => ({ title: item.userName, key: item.userId, isLeaf: true })), children?.length),
  122. );
  123. resolve();
  124. })
  125. });
  126. }
  127. return <Modal
  128. title={<strong>设置客服组</strong>}
  129. open={visible}
  130. onCancel={onClose}
  131. onOk={handleOk}
  132. className='modalResetCss'
  133. width={750}
  134. bodyStyle={{ padding: 0 }}
  135. confirmLoading={updateCustomerServiceGroup.loading}
  136. >
  137. <Spin spinning={getCorpDepartmentList.loading || loading}>
  138. <div className='settingsEnterprise'>
  139. <div className='settingsEnterprise-left'>
  140. <div>
  141. <NTree
  142. treeData={treeData}
  143. loadData={onLoadData}
  144. onSelect={(selectedKeys) => {
  145. console.log('selected', selectedKeys);
  146. setUserInfoList(selectedKeys.map((item: any) => ({ userId: item.value, userName: item.label, ...item })))
  147. }}
  148. selectedKeys={userInfoList.map(({ userId, userName, ...item }) => ({ value: userId, label: userName, ...item }))}
  149. />
  150. </div>
  151. </div>
  152. <div className='settingsEnterprise-right'>
  153. <div>
  154. <div className='settingsEnterprise-right-title'>已选 <span>{userInfoList?.length || 0}</span> 个客服</div>
  155. <div className='settingsEnterprise-right-list'>
  156. {userInfoList.map(item => {
  157. return <div className='list-item' key={item.userId}>
  158. <div style={item?.state === 1 ? { color: 'red' } : {}}>
  159. <UserOutlined />
  160. <Typography.Text ellipsis style={item?.state === 1 ? { color: 'red' } : {}}>{item?.userName || item.msg || item.userId}</Typography.Text>
  161. </div>
  162. <a onClick={() => {
  163. setUserInfoList(userInfoList.filter(item2 => item2.userId !== item.userId))
  164. }}><CloseOutlined /></a>
  165. </div>
  166. })}
  167. </div>
  168. </div>
  169. </div>
  170. </div>
  171. </Spin>
  172. </Modal>
  173. };
  174. export default React.memo(SettingsEnterprise);