menu.tsx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * @Author: your name
  3. * @Date: 2022-01-14 14:03:42
  4. * @LastEditTime: 2022-11-30 15:48:33
  5. * @LastEditors: code4eat awesomedema@gmail.com
  6. * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  7. * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/hospManage/modals/menu.tsx
  8. */
  9. import React, { Key, useEffect, useState } from 'react';
  10. import KCTable from '@/components/kcTable';
  11. import { Popconfirm } from 'antd';
  12. import { Input, Transfer, Tree } from 'antd';
  13. import { getAllMenus, getAllMenusDataType, getHospAllMenus } from '@/service/menu';
  14. import { ProColumns } from '@ant-design/pro-table';
  15. import type { MenuItemDataType } from '@/service/menu';
  16. import { DownOutlined, FileOutlined, RightOutlined } from '@ant-design/icons';
  17. import './style.less';
  18. import { MenuTypes } from '@/constant';
  19. import { getValsFromTree } from '@/utils';
  20. import type { TransferDirection, TransferItem } from 'antd/es/transfer';
  21. import type { DataNode } from 'antd/es/tree';
  22. const { Search } = Input;
  23. export interface MenuEditerType {
  24. value?: React.Key[] | React.Key[];
  25. onChange?: (selectedRowKeys: React.Key[], selectedRows?: any[]) => {};
  26. noAction?: boolean;
  27. hospId?: number | string;
  28. }
  29. const MenuEditer: React.FC<MenuEditerType> = ({ value = [], onChange, noAction = false, hospId }) => {
  30. const getData = async () => {
  31. if (hospId) {
  32. const resp = await getHospAllMenus(hospId);
  33. if (resp) {
  34. const data = resp.allMenuVO;
  35. const convertData = (data: Array<any>) => {
  36. data.forEach((item) => {
  37. item.children = item.child;
  38. if (item.child) {
  39. convertData(item.child);
  40. }
  41. });
  42. };
  43. convertData(data);
  44. setDataSource(data);
  45. }
  46. } else {
  47. const resp = await getAllMenus();
  48. const data = resp.list ? resp.list : [];
  49. setDataSource(data);
  50. }
  51. };
  52. const [dataSource, setDataSource] = useState<any[]>([]);
  53. const [targetKeys, setTargetKeys] = useState<string[]>([]);
  54. const [_selectedKeys, set__selectedKeys] = useState<string[]>([]);
  55. const [sourceSelectedKeys, set_sourceSelectedKeys] = useState<string[]>([]);
  56. const onTransFerChange = (keys: string[]) => {
  57. let _keys = Array.from(new Set(keys));
  58. setTargetKeys(_keys);
  59. onChange && onChange(_keys);
  60. };
  61. interface TreeTransferProps {
  62. dataSource: MenuItemDataType[];
  63. targetKeys: string[];
  64. onChange: (targetKeys: string[], direction: TransferDirection, moveKeys: string[]) => void;
  65. }
  66. const isChecked = (selectedKeys: (string | number)[], eventKeys: (string | number)[]) => {
  67. // console.log({selectedKeys,eventKeys});
  68. const isIncludesFunc = (arr1: (string | number)[], arr2: (string | number)[]) => {
  69. if (arr2.length == 0) {
  70. return true;
  71. }
  72. return arr2.every((item) => arr1.includes(item));
  73. };
  74. return isIncludesFunc(selectedKeys, eventKeys);
  75. };
  76. const generateTree = (treeNodes: MenuItemDataType[] = [], checkedKeys: string[] = []): any[] => {
  77. return treeNodes.map(({ children, menuId, name, ...props }) => ({
  78. key: menuId,
  79. title: name,
  80. disabled: checkedKeys.includes(menuId as string),
  81. children: generateTree(children, checkedKeys),
  82. ...props,
  83. }));
  84. };
  85. const onSelectChangeHandle = (_sourceSelectedKeys: Key[], targetSelectedKeys: Key[]) => {
  86. set_sourceSelectedKeys(_sourceSelectedKeys as string[]);
  87. // set_selectedKeysVal(sourceSelectedKeys as string[]);
  88. // setTargetKeys(targetSelectedKeys as string[]);
  89. };
  90. const TreeTransfer = ({ dataSource, targetKeys, ...restProps }: TreeTransferProps) => {
  91. const transferDataSource: MenuItemDataType[] = [];
  92. function flatten(list: MenuItemDataType[] = []) {
  93. list.forEach((item) => {
  94. transferDataSource.push(item as MenuItemDataType);
  95. flatten(item.children);
  96. });
  97. }
  98. flatten(dataSource);
  99. return (
  100. <Transfer
  101. {...restProps}
  102. listStyle={{ width: 100, height: 500 }}
  103. targetKeys={targetKeys}
  104. rowKey={(record) => record.menuId}
  105. dataSource={transferDataSource}
  106. className="tree-transfer"
  107. // onSelectChange={onSelectChangeHandle}
  108. // selectedKeys={_selectedKeys}
  109. render={(item) => item.name!}
  110. showSelectAll={true}
  111. >
  112. {({ direction, onItemSelect, selectedKeys, onItemSelectAll }) => {
  113. if (direction === 'left') {
  114. const checkedKeys = [...selectedKeys, ...targetKeys];
  115. return (
  116. <Tree
  117. blockNode
  118. checkable
  119. checkStrictly={false}
  120. defaultExpandAll
  121. height={460}
  122. checkedKeys={checkedKeys}
  123. treeData={generateTree(dataSource, targetKeys)}
  124. onCheck={(keys, { node, halfCheckedKeys, ...rest }) => {
  125. // console.log({keys,node,rest});
  126. // 差集
  127. let difference = (keys as Key[]).filter((v) => !targetKeys.includes(v as string));
  128. const map = (list: any, cb: any) => {
  129. return list.reduce((res: any, v: any) => {
  130. res.push(cb(v));
  131. if (Array.isArray(v.child)) res = res.concat(map(v.child, cb));
  132. return res;
  133. }, []);
  134. };
  135. if (!node.checked) {
  136. //选中
  137. onItemSelectAll(difference as string[], true);
  138. } else {
  139. //取消勾选
  140. const cancelKeys = map(node.children, (v: any) => v.key);
  141. onItemSelectAll([node.key, ...cancelKeys, ...(halfCheckedKeys as Key[])] as string[], false);
  142. }
  143. }}
  144. onSelect={(keys, { node: { key } }) => {}}
  145. />
  146. );
  147. }
  148. }}
  149. </Transfer>
  150. );
  151. };
  152. useEffect(() => {
  153. setTargetKeys(value as string[]);
  154. }, [value]);
  155. useEffect(() => {
  156. getData();
  157. }, []);
  158. return (
  159. <div className="MenuEditer">
  160. <TreeTransfer dataSource={dataSource} targetKeys={targetKeys} onChange={onTransFerChange} />
  161. </div>
  162. );
  163. };
  164. export default MenuEditer;