index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. import React, { useState, useEffect, useCallback, useRef } from 'react';
  2. import { FormattedMessage, history, useModel } from 'umi';
  3. import { Spin, Popover, Dropdown, MenuProps } from 'antd';
  4. import styles from './index.less';
  5. import cx from 'classnames';
  6. import PageHeader from '@/sagacare_components/PageHeader';
  7. import Search from '@/sagacare_components/Search';
  8. import Table from '@/sagacare_components/Table';
  9. import Empty from './components/Empty';
  10. import PersonModal from './components/personModal';
  11. import ImportModal from './components/importModal';
  12. import { EllipsisOutlined, InfoCircleOutlined } from '@ant-design/icons';
  13. import Icon from '@/tenants-ui/SgIcon';
  14. import {
  15. queryUserList,
  16. queryCompanyOAById,
  17. queryControlSpaceCompany,
  18. } from '@/services/sagacare_service/member';
  19. const Member: React.FC = () => {
  20. const { initialState } = useModel('@@initialState');
  21. const [perVisible, setPerVisible] = useState(false); //人员对话框显示
  22. const [importVisible, setImportVisible] = useState(false); //人员对话框显示
  23. const [temporary, setTemporary] = useState(false); //是否是临时成员添加
  24. const [invalidSign, setInvalidSign] = useState(false); //显示作废
  25. const [spaceMap, setSpaceMap] = useState<any>();
  26. const [searchStr, setSearchStr] = useState();
  27. const [isSyncOa, setIsSyncOa] = useState(true); //是否是OA同步
  28. const [userList, setUserList] = useState<any>([]);
  29. const [total, setTotal] = useState();
  30. const [loading, setLoading] = useState(false);
  31. const [page, setPage] = useState({
  32. pageNum: 1,
  33. pageSize: 10,
  34. });
  35. const [checkUser, setCheckUser] = useState({}); //查看的人
  36. const [checkSign, setCheckSign] = useState('add'); // 三种状态 查看 编辑 新增
  37. const [refreshNum, setRefreshNum] = useState(0); //刷新列表
  38. const [showFilterIds, setShowFilterIds] = useState([]);
  39. // const statusArr = {
  40. // 2: '正常',
  41. // 3: '待激活',
  42. // 5: '已作废',
  43. // };
  44. const userTpeyArr = {
  45. 1: '普通成员',
  46. 2: '临时成员',
  47. 3: '管理员',
  48. };
  49. const [sorter, setSorter] = useState<any>({
  50. updateDate: 'DESC', //'ASC' : 'DESC'
  51. });
  52. const getColumns = () => {
  53. return [
  54. {
  55. title: '姓名',
  56. dataIndex: 'name',
  57. width: 140,
  58. render: function (content, item, index) {
  59. return <div>{content}</div>;
  60. },
  61. },
  62. {
  63. title: '类型',
  64. dataIndex: 'manageUserType',
  65. filteredValue: showFilterIds,
  66. single: false,
  67. filters: [
  68. { value: 1, label: '普通成员' },
  69. { value: 2, label: '临时成员' },
  70. { value: 3, label: '管理员' },
  71. ],
  72. render: function (content, item, index) {
  73. return <span>{userTpeyArr[content]}</span>;
  74. },
  75. },
  76. {
  77. title: '手机号',
  78. dataIndex: 'phone',
  79. },
  80. {
  81. title: '职务',
  82. dataIndex: 'job',
  83. },
  84. {
  85. title: '常驻工区',
  86. dataIndex: 'permanentSpaceName',
  87. },
  88. {
  89. title: '可控工区',
  90. dataIndex: 'isAllControl',
  91. render: function (content, item, index) {
  92. return <span>{content ? '部分可控' : '全部可控'}</span>;
  93. },
  94. },
  95. {
  96. title: '更新时间',
  97. dataIndex: 'updateDate',
  98. sorter: true,
  99. sortered: sorter.updateDate,
  100. },
  101. {
  102. title: '状态',
  103. dataIndex: 'status',
  104. render: function (content, item, index) {
  105. //debugger;
  106. return (
  107. <div>
  108. <span
  109. className={cx(styles.circle, {
  110. [styles.activated]: content == '待激活',
  111. })}
  112. ></span>
  113. <span>{content}</span>
  114. </div>
  115. );
  116. },
  117. },
  118. {
  119. title: '',
  120. dataIndex: '',
  121. render: function (content, item) {
  122. const menuItems: MenuProps['items'] = [
  123. {
  124. key: '1',
  125. label: (
  126. <div
  127. className={styles.operateLi}
  128. onClick={() => {
  129. checkPerson(item);
  130. }}
  131. >
  132. 查看
  133. </div>
  134. ),
  135. },
  136. {
  137. key: '2',
  138. label: (
  139. <div
  140. className={styles.operateLi}
  141. onClick={() => {
  142. editPerson(item);
  143. }}
  144. >
  145. 编辑
  146. </div>
  147. ),
  148. },
  149. {
  150. key: '3',
  151. label: (
  152. <div
  153. className={cx(styles.operateLi, { [styles.disabled]: item.oaId })}
  154. onClick={() => {
  155. invalidPerson(item);
  156. }}
  157. >
  158. 作废
  159. </div>
  160. ),
  161. },
  162. ];
  163. return (
  164. <Dropdown menu={{ items: menuItems }}>
  165. <EllipsisOutlined style={{ color: '#4D5262', fontSize: '20px' }} />
  166. </Dropdown>
  167. );
  168. },
  169. },
  170. ];
  171. };
  172. const goToInvalid = () => {
  173. history.push(`/member/invalid`);
  174. };
  175. const refreshList = () => {
  176. setRefreshNum(refreshNum + 1);
  177. };
  178. const onClose = () => {
  179. setPerVisible(false);
  180. };
  181. const onImClose = () => {
  182. setImportVisible(false);
  183. };
  184. const showImport = () => {
  185. setImportVisible(true);
  186. };
  187. useEffect(() => {
  188. var paramObj = {
  189. criteria: {
  190. param: searchStr,
  191. status: 1,
  192. companyId: initialState?.currentUser?.companyId,
  193. // manageUserType: [],
  194. },
  195. page: page.pageNum,
  196. size: page.pageSize,
  197. orders: [
  198. {
  199. column: 'updateDate',
  200. asc: sorter.updateDate == 'DESC' ? true : false,
  201. },
  202. ],
  203. };
  204. setLoading(true);
  205. if (showFilterIds.length > 0) {
  206. paramObj.criteria = { ...paramObj.criteria, ...{ manageUserType: showFilterIds } };
  207. }
  208. queryUserList(paramObj)
  209. .then((res) => {
  210. debugger;
  211. setLoading(false);
  212. var uarr = res.content || [];
  213. var count = res.count || 0;
  214. setUserList(uarr);
  215. setTotal(count);
  216. })
  217. .catch((err) => {
  218. setLoading(false);
  219. });
  220. }, [searchStr, showFilterIds, page, sorter, refreshNum]);
  221. useEffect(() => {
  222. //查询受控列表
  223. var paramObj = {
  224. criteria: {
  225. companyId: initialState?.currentUser?.companyId,
  226. },
  227. };
  228. queryControlSpaceCompany(paramObj)
  229. .then((res) => {
  230. var data = res.data || {};
  231. setSpaceMap(data);
  232. })
  233. .catch((err) => {});
  234. queryCompanyOAById({ companyId: initialState?.currentUser?.companyId })
  235. .then((res) => {
  236. var isSyncOa = res?.isSyncOa;
  237. setIsSyncOa(isSyncOa == 1 ? true : false);
  238. })
  239. .catch((err) => {});
  240. }, []);
  241. const checkPerson = (item) => {
  242. setPerVisible(true);
  243. setInvalidSign(false);
  244. setCheckSign('check'); //设置为查看状态
  245. setCheckUser(item);
  246. setTemporary(false);
  247. };
  248. const editPerson = (item) => {
  249. setPerVisible(true);
  250. setInvalidSign(false);
  251. setCheckSign('edit');
  252. setCheckUser(item);
  253. setTemporary(false);
  254. };
  255. //作废用户
  256. const invalidPerson = (item) => {
  257. setInvalidSign(true);
  258. setPerVisible(true);
  259. setCheckUser(item);
  260. setTemporary(false);
  261. };
  262. //添加临时用户
  263. const addTemporaryPerson = () => {
  264. setPerVisible(true);
  265. setInvalidSign(false);
  266. setCheckSign('add');
  267. setCheckUser({});
  268. setTemporary(true);
  269. };
  270. const addNewPerson = () => {
  271. setPerVisible(true);
  272. setInvalidSign(false);
  273. setCheckSign('add');
  274. setCheckUser({});
  275. setTemporary(false);
  276. };
  277. return (
  278. <div className={styles.memberwrap}>
  279. <PageHeader
  280. title={<FormattedMessage id="menu.member" />}
  281. action={
  282. <div className={styles.headerRight}>
  283. <Search changeSearchStr={setSearchStr} />
  284. {isSyncOa ? (
  285. <>
  286. <div className={styles.allIn}>
  287. <InfoCircleOutlined />
  288. 已开启OA同步
  289. </div>
  290. <div
  291. className={styles.invalid}
  292. onClick={() => {
  293. goToInvalid();
  294. }}
  295. >
  296. 已作废
  297. </div>
  298. <div className={styles.addButton} onClick={addTemporaryPerson}>
  299. 添加临时成员
  300. </div>
  301. </>
  302. ) : (
  303. <>
  304. <div className={styles.allIn} onClick={showImport}>
  305. <Icon
  306. className=""
  307. type="import"
  308. style={{
  309. color: '#4D5262',
  310. fontSize: '15px',
  311. marginRight: '6px',
  312. }}
  313. ></Icon>
  314. 批量导入
  315. </div>
  316. <div
  317. className={styles.invalid}
  318. onClick={() => {
  319. goToInvalid();
  320. }}
  321. >
  322. <Icon
  323. className=""
  324. type="cancel"
  325. style={{
  326. color: '#4D5262',
  327. fontSize: '15px',
  328. marginRight: '6px',
  329. }}
  330. ></Icon>
  331. 已作废
  332. </div>
  333. <div className={styles.addButton} onClick={addNewPerson}>
  334. 新增成员
  335. </div>
  336. </>
  337. )}
  338. </div>
  339. }
  340. />
  341. <div className={styles.bottomTable}>
  342. <Table
  343. columns={getColumns()}
  344. rowKey="userId"
  345. dataSource={userList}
  346. loading={loading}
  347. page={page}
  348. total={total}
  349. pagination={!!userList.length}
  350. onFilterChange={(key, options) => {
  351. debugger;
  352. setShowFilterIds(options);
  353. }}
  354. onRowClick={(record) => {}}
  355. onSortChange={(col: any, direction: string) => {
  356. setSorter({ [col['dataIndex']]: direction });
  357. }}
  358. onPageChange={(p) => {
  359. setPage(p);
  360. }}
  361. />
  362. {!userList.length && !loading && <Empty />}
  363. </div>
  364. {perVisible && (
  365. <PersonModal
  366. invalidSign={invalidSign}
  367. temporary={temporary}
  368. checkUser={checkUser}
  369. checkSign={checkSign}
  370. onClose={onClose}
  371. setCheckSign={setCheckSign}
  372. setInvalidSign={setInvalidSign}
  373. spaceMap={spaceMap}
  374. refreshList={refreshList}
  375. ></PersonModal>
  376. )}
  377. {importVisible && <ImportModal onClose={onImClose}></ImportModal>}
  378. </div>
  379. );
  380. };
  381. export default Member;