index.tsx 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. /*
  2. * @Author: code4eat awesomedema@gmail.com
  3. * @Date: 2022-12-16 09:42:52
  4. * @LastEditors: code4eat awesomedema@gmail.com
  5. * @LastEditTime: 2023-09-25 13:57:31
  6. * @FilePath: /BudgetManaSystem/src/pages/budgetMana/monthlySet/index.tsx
  7. * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  8. */
  9. import BMSPagecontainer from '@/components/BMSPageContainer';
  10. import { useEffect, useRef, useState } from 'react';
  11. import './style.less';
  12. import { TreeProps, Input, Modal, message, Popover, Table, Switch, Tooltip, DatePicker, ConfigProvider } from 'antd';
  13. import { DataNode } from 'antd/es/tree';
  14. import expandedIcon from '../../../../static/treenode_open.png';
  15. import closeIcon from '../../../../static/treenode_collapse.png';
  16. import { BMSTable } from '@/components/BMSTable';
  17. import { ActionType, ProColumns, ProFormDatePicker, ProFormDigit, ProFormInstance, ProFormSelect } from '@ant-design/pro-components';
  18. import { createFromIconfontCN } from '@ant-design/icons';
  19. import { autoComputedReq, checkCurrentRequest, checkRequest, commitRequest, getCurrentCheckStatusReq, getCurrentCommitStatusReq, getCurrentUnitCheckStatusReq, getSecondaryDistriComputeTableData, getTreeData, getTreeDataRespType, save } from './service';
  20. import { getComputeDate } from '@/pages/Home/service';
  21. import React from 'react';
  22. import DirectoryTree from 'antd/es/tree/DirectoryTree';
  23. import { getDeepestTreeData } from '@/utils/tooljs';
  24. import { getCurrentCheckStatus } from '@/services/auth';
  25. import { useLocation } from '@umijs/max';
  26. import { useAccess } from '@umijs/max';
  27. import { getParamsData } from '@/pages/setting/baseSetting/paramsMana/service';
  28. import 'moment/locale/zh-cn';
  29. import locale from 'antd/es/date-picker/locale/zh_CN';
  30. import moment from 'moment';
  31. import { getJiezhuanStatus } from '@/pages/budgetMana/monthlySet/service';
  32. import { formatMoneyNumber } from '@/utils/format';
  33. const SearchIcon = createFromIconfontCN({
  34. scriptUrl: '',
  35. });
  36. export type TableListItem = {
  37. key: number;
  38. name: string;
  39. };
  40. const SecondaryDitriComputed: React.FC = () => {
  41. const location = useLocation();
  42. const access = useAccess();
  43. const userFunctionInThispage = access.whatCanIDoInThisPage(location.pathname);
  44. const [ifCheckPage, set_ifCheckPage] = useState(false); //是否为二次分配审核页面
  45. const [treeData, set_treeData] = useState<getTreeDataRespType[]>([]);
  46. const [treeDataDefault, set_treeDataDefault] = useState<getTreeDataRespType[]>([]);
  47. const [tableColumn, set_tableColumn] = useState<ProColumns[]>([]);
  48. const [currentSelectedTreeNode, set_currentSelectedTreeNode] = useState<any | undefined>();
  49. const [currentComputeDate, set_currentComputeDate] = useState<string | undefined>();
  50. const [ifShowTip, set_ifShowTip] = useState(false);
  51. const [commitStatus, set_commitStatus] = useState('0'); //提交状态
  52. const [empFilterParams, set_empFilterParams] = useState<any | undefined>(undefined);
  53. const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  54. const [searchValue, setSearchValue] = useState('');
  55. const [autoExpandParent, setAutoExpandParent] = useState(true);
  56. const [ifEditMode, set_ifEditMode] = useState(false);
  57. const [auditType, set_auditType] = useState('0'); //审核状态
  58. const [currentUnitAuditType, set_currentUnitAuditType] = useState('0'); //当前单元审核状态
  59. const tableRef = useRef<ActionType>();
  60. const [needSaveData, set_needSaveData] = useState<any | undefined>(undefined);
  61. const [inputsRefKeys, set_inputsRefKeys] = useState<string[]>([]);
  62. const inputsRef = useRef<{ [key: string]: any }>({});
  63. const [pageData, set_pageData] = useState({ total: 0, completedTotal: 0, leftTotal: 0 });
  64. const [dataSource, set_dataSource] = useState([]);
  65. const [currentInputRefKeys, set_currentInputRefKeys] = useState<string | undefined>(undefined);
  66. const [tableH, set_tableH] = useState(0);
  67. const [currentTreeDataFilter, set_currentTreeDataFilter] = useState({ name: '全部单元', code: 0 });
  68. const [treeFilterVisible, set_treeFilterVisible] = useState(false);
  69. const [ifBanAllAction, set_ifBanAllAction] = useState(true); //是否掩藏所有操作
  70. const column: ProColumns[] = [
  71. // {
  72. // title: '工号',
  73. // width:120,
  74. // fixed: 'left',
  75. // dataIndex: 'account',
  76. // },
  77. {
  78. title: '姓名',
  79. width: 140,
  80. fixed: 'left',
  81. dataIndex: 'name',
  82. renderText(text, record, index, action) {
  83. return `${record.name}(${record.account})`
  84. },
  85. },
  86. ];
  87. const onSelect: TreeProps['onSelect'] = (selectedKeys, info: any) => {
  88. // console.log('selected', selectedKeys, info);
  89. if (!ifEditMode) {
  90. //编辑时,需要先保存后切换
  91. const { node } = info;
  92. if (!node.child) {
  93. set_currentSelectedTreeNode(node);
  94. }
  95. } else {
  96. Modal.confirm({
  97. title: '提示', content: '当前存在编辑未保存,请先保存!', okText: '确定',
  98. cancelText: '取消',
  99. })
  100. }
  101. };
  102. const getCurrentComputeDate = async () => {
  103. const resp = await getComputeDate();
  104. set_currentComputeDate(resp);
  105. }
  106. const getCheckStatus = async (computeDate: string) => {
  107. const resp = await getCurrentCheckStatusReq(computeDate);
  108. set_auditType(`${resp}`); //0 未审核 1 已审核
  109. }
  110. const getCurrentUnitCheckStatus = async () => {
  111. if (currentSelectedTreeNode) {
  112. const resp = await getCurrentUnitCheckStatusReq(currentComputeDate as string, currentSelectedTreeNode.code);
  113. set_currentUnitAuditType(`${resp}`); //0 未审核 1 已审核
  114. }
  115. }
  116. const getCurrentCommitStatus = async () => {
  117. if (currentSelectedTreeNode) {
  118. const resp = await getCurrentCommitStatusReq({
  119. computeDate: currentComputeDate as string,
  120. unitCode: currentSelectedTreeNode.code
  121. });
  122. set_commitStatus(`${resp}`);
  123. }
  124. }
  125. const gennerateColumns = (data: { title: any; userList: any; }, inputsRefKeys?: string[]) => {
  126. const { title } = data;
  127. const _columns = title.map((item: any, index: number) => {
  128. return {
  129. title: item.name,
  130. dataIndex: `${item.code}`,
  131. width: 160,
  132. renderText: (_: any, record: any) => {
  133. if (ifEditMode) {
  134. let _val = _;
  135. return <ProFormDigit noStyle min={-1000000000} fieldProps={{
  136. ref: ref => {
  137. inputsRef.current[`${record.account}-${item.code}`] = ref;
  138. //console.log({ref});
  139. },
  140. onBlur: () => {
  141. const updatedUserList = needSaveData.userList.map((a: any) => {
  142. if (a.account == record.account) {
  143. const arr = a.itemValue.map((b: any) => {
  144. if (b.code == item.code) {
  145. return { ...b, value: _val ? _val : 0 } //value有为undefined的可能
  146. } else {
  147. return b
  148. }
  149. });
  150. return { ...a, itemValue: arr }
  151. } else {
  152. return a
  153. }
  154. });
  155. set_needSaveData({ ...needSaveData, userList: updatedUserList })
  156. },
  157. onChange(value) {
  158. _val = value ? value : 0;
  159. },
  160. onPressEnter: (event: any) => {
  161. if (event.code === 'Enter') {
  162. event.preventDefault();
  163. const value = event.target.value ? Number(event.target.value) : 0;
  164. const updatedUserList = needSaveData.userList.map((a: any) => {
  165. if (a.account == record.account) {
  166. const arr = a.itemValue.map((b: any) => {
  167. if (b.code == item.code) {
  168. return { ...b, value: value ? value : 0 } //value有为undefined的可能
  169. } else {
  170. return b
  171. }
  172. });
  173. return { ...a, itemValue: arr }
  174. } else {
  175. return a
  176. }
  177. });
  178. set_needSaveData({ ...needSaveData, userList: updatedUserList });
  179. const index = inputsRefKeys ? inputsRefKeys.findIndex(a => a == `${record.account}-${item.code}`) : -1;
  180. //console.log({index,input:inputsRef.current,inputsRefKeys});
  181. const nextInput = inputsRefKeys ? inputsRef.current[inputsRefKeys[index + 1]] : null;
  182. if (nextInput) {
  183. inputsRefKeys && set_currentInputRefKeys(inputsRefKeys[index + 1]);
  184. nextInput.focus();
  185. }
  186. }
  187. },
  188. onFocus: () => set_currentInputRefKeys(`${record.account}-${item.code}`),
  189. defaultValue: _,
  190. }} width={120} />
  191. } else {
  192. return <span style={{ display: 'inline-block', width: 80 }}>{formatMoneyNumber(_)}</span>
  193. }
  194. },
  195. }
  196. });
  197. set_tableColumn([...column, ..._columns, {
  198. title: '总奖金',
  199. dataIndex: 'totalScore',
  200. width: 120,
  201. fixed: 'right',
  202. renderText(text, record, index, action) {
  203. return formatMoneyNumber(text);
  204. },
  205. },
  206. ]);
  207. }
  208. const getTableData = async (params: any) => {
  209. if (currentSelectedTreeNode && currentComputeDate) {
  210. const resp = await getSecondaryDistriComputeTableData({
  211. computeDate: currentComputeDate,
  212. unitCode: currentSelectedTreeNode.code,
  213. ...params,
  214. });
  215. if (resp) {
  216. set_needSaveData(resp);
  217. //buildTableData(resp);
  218. }
  219. }
  220. return []
  221. }
  222. const buildTableData = (resp: any, inputsRefKeys?: string[]) => {
  223. const { title, userList } = resp;
  224. const _columns = gennerateColumns(resp, inputsRefKeys);
  225. const data = userList.map((item: any) => {
  226. let total = 0;
  227. let rowData: { [key: string]: any } = {};
  228. item.itemValue.forEach((b: any) => {
  229. const needTitle = title.filter((a: any) => a.code == b.code);
  230. if (needTitle.length > 0) {
  231. rowData[`${needTitle[0].code}`] = b.value
  232. }
  233. total = total + b.value;
  234. });
  235. return { ...item, ...rowData, id: Math.random(), _columns, totalScore: Number(total.toFixed(2)) }
  236. });
  237. const compeltedTotal = data.reduce((prev: any, cur: any) => prev + cur.totalScore, 0);
  238. const leftTotal = resp.totalBonus - compeltedTotal;
  239. set_pageData({ ...pageData, total: resp.totalBonus?resp.totalBonus.toFixed(2):0, completedTotal: compeltedTotal.toFixed(2), leftTotal: Number(leftTotal.toFixed(2)) });
  240. set_dataSource(data);
  241. }
  242. const commitBtnhandle = async (type?: number) => {
  243. //console.log({type});
  244. /**
  245. * type 1 单个 2 全部
  246. * 提交界面不需要type
  247. */
  248. const handle = async (ifCheckCommit: string) => {
  249. if (type == 1) {
  250. //审核单个
  251. const resp = await checkCurrentRequest({
  252. computeDate: currentComputeDate as string,
  253. auditType: currentUnitAuditType == '1' ? '0' : '1', //1 审核 0 取消审核
  254. unitCode: currentSelectedTreeNode.code,
  255. type: ifCheckCommit
  256. });
  257. if (resp) {
  258. message.success('操作成功!');
  259. getTreeReqFunc(currentComputeDate as string, ifCheckPage ? '1' : '0');
  260. getCurrentUnitCheckStatus();
  261. }
  262. }
  263. if (type == 2) {
  264. const resp = await checkRequest({
  265. computeDate: currentComputeDate as string,
  266. auditType: auditType == '1' ? '0' : '1', //1 审核 0 取消审核
  267. type: ifCheckCommit
  268. });
  269. if (resp) {
  270. message.success('操作成功!');
  271. getTreeReqFunc(currentComputeDate as string, ifCheckPage ? '1' : '0');
  272. getCheckStatus(currentComputeDate as string);
  273. }
  274. }
  275. }
  276. if (ifCheckPage && type) {
  277. const checkCondition = await getParamsData({ pageSize: 500 });
  278. if (checkCondition) {
  279. const needParamsVal = checkCondition.list.filter(a => a.code == '1664510428258115584'); //判断未提交是否可以审核
  280. if (needParamsVal.length > 0) {
  281. if (needParamsVal[0].value == '0') {
  282. handle(needParamsVal[0].value);
  283. } else {
  284. handle(needParamsVal[0].value);
  285. }
  286. }
  287. }
  288. } else {
  289. if (commitStatus == '1') {
  290. Modal.confirm({
  291. title: '注意',
  292. okText: '确定',
  293. cancelText: '取消',
  294. content: `${commitStatus == '1' ? '取消提交' : '提交'}当前选择的核算单元的数据?`,
  295. onOk: async () => {
  296. const resp = await commitRequest({
  297. computeDate: currentComputeDate as string,
  298. unitCode: currentSelectedTreeNode.code,
  299. type: commitStatus == '1' ? '0' : '1', //1 提交 0 取消
  300. });
  301. if (resp) {
  302. message.success('提交成功!');
  303. getTreeReqFunc(currentComputeDate as string, ifCheckPage ? '1' : '0');
  304. getCurrentCommitStatus();
  305. }
  306. }
  307. })
  308. } else {
  309. if(pageData.leftTotal != 0){
  310. Modal.confirm({
  311. title: '提交时需有单元的剩余分配金额必须是0',
  312. okText: '确定',
  313. cancelText: '取消',
  314. })
  315. }else {
  316. Modal.confirm({
  317. title: '注意',
  318. okText: '确定',
  319. cancelText: '取消',
  320. content: `${commitStatus == '1' ? '取消提交' : '提交'}当前选择的核算单元的数据?`,
  321. onOk: async () => {
  322. const resp = await commitRequest({
  323. computeDate: currentComputeDate as string,
  324. unitCode: currentSelectedTreeNode.code,
  325. type: commitStatus == '1' ? '0' : '1', //1 提交 0 取消
  326. });
  327. if (resp) {
  328. message.success('提交成功!');
  329. getTreeReqFunc(currentComputeDate as string, ifCheckPage ? '1' : '0');
  330. getCurrentCommitStatus();
  331. }
  332. }
  333. })
  334. }
  335. }
  336. }
  337. }
  338. const dataList: any[] = [];
  339. const getParentKey = (key: React.Key, tree: any[]): React.Key => {
  340. let parentKey: React.Key;
  341. for (let i = 0; i < tree.length; i++) {
  342. const node = tree[i];
  343. if (node.child) {
  344. if (node.child.some((item: { code: React.Key; }) => item.code === key)) {
  345. parentKey = node.code;
  346. } else if (getParentKey(key, node.child)) {
  347. parentKey = getParentKey(key, node.child);
  348. }
  349. }
  350. }
  351. return parentKey!;
  352. };
  353. const onTreeSearchKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  354. const { value } = e.target;
  355. const newExpandedKeys = dataList
  356. .map((item) => {
  357. if (item.name.indexOf(value) > -1) {
  358. return getParentKey(item.code, treeData);
  359. }
  360. return null;
  361. });
  362. const b = newExpandedKeys.filter((item, i, self) => item && self.indexOf(item) === i);
  363. setExpandedKeys(newExpandedKeys as React.Key[]);
  364. setSearchValue(value);
  365. setAutoExpandParent(true);
  366. }
  367. //左侧树结构筛选
  368. const changeTreeDataFilter = (obj: any) => {
  369. set_currentTreeDataFilter(obj);
  370. set_treeFilterVisible(false);
  371. interface Node {
  372. map: boolean;
  373. child?: Node[];
  374. }
  375. function filterNodes(node: Node): Node | null {
  376. if (node.map === (obj.code == 1 ? false : true) && (!node.child || node.child.length === 0)) {
  377. return node; // 如果节点map为false并且是叶子节点,返回该节点
  378. }
  379. if (Array.isArray(node.child)) {
  380. // 对每个子节点递归执行此过程
  381. let child = node.child.map(filterNodes).filter((n): n is Node => n !== null);
  382. if (child.length > 0) {
  383. // 如果有任何子节点的map属性为false,返回包含这些子节点的新节点
  384. return { ...node, child: child };
  385. }
  386. }
  387. // 如果节点map为true,或者所有子节点的map都为true,返回null
  388. return null;
  389. }
  390. if (obj.code == 0) {
  391. set_treeData(treeDataDefault);
  392. } else {
  393. const result = treeDataDefault.map(a => {
  394. return filterNodes(a);
  395. });
  396. set_treeData(result.filter(b => b != null) as any);
  397. }
  398. }
  399. const onExpand = (newExpandedKeys: React.Key[]) => {
  400. setExpandedKeys(newExpandedKeys);
  401. setAutoExpandParent(false);
  402. };
  403. const generateList = (data: getTreeDataRespType[]) => {
  404. for (let i = 0; i < data.length; i++) {
  405. const node = data[i];
  406. const { code, name } = node;
  407. dataList.push({ code: code, name: name });
  408. if (node.child) {
  409. generateList(node.child);
  410. }
  411. }
  412. };
  413. generateList(treeData as any);
  414. const getTreeReqFunc = async (computeDate: string, type: string) => {
  415. const resp = await getTreeData(computeDate, type);
  416. if(resp){
  417. set_treeDataDefault(resp);
  418. }
  419. }
  420. const handleResize = (e: any) => {
  421. const wH = e.target.innerHeight;
  422. const tableHeight = wH - 290;
  423. set_tableH(tableHeight);
  424. }
  425. function doResize() {
  426. setTimeout(() => {
  427. const ev: any = new Event('resize');
  428. window.dispatchEvent(ev);
  429. }, 0)
  430. }
  431. const autoComputed =async () => {
  432. const resp = await autoComputedReq({computeDate:currentComputeDate as string,unitCode:currentSelectedTreeNode.code});
  433. if(resp){
  434. message.success('操作成功!');
  435. getTableData({});
  436. }
  437. }
  438. const computeHandle = () => {
  439. Modal.confirm({
  440. title: '注意',
  441. content: '重新计算会覆盖原有数据,确定要继续计算操作?',
  442. onOk(...args) {
  443. autoComputed();
  444. },
  445. })
  446. }
  447. const saveHandle = async () => {
  448. const resp = await save(needSaveData);
  449. if (resp) {
  450. message.success('操作成功!');
  451. set_ifEditMode(false);
  452. }
  453. }
  454. const getJiezhuanStatusHandle = async () => {
  455. const resp = await getJiezhuanStatus(currentComputeDate as string);
  456. if (resp == 2) {
  457. set_ifBanAllAction(true);
  458. } else {
  459. set_ifBanAllAction(false);
  460. }
  461. }
  462. useEffect(() => {
  463. if (currentComputeDate) {
  464. getTreeReqFunc(currentComputeDate, ifCheckPage ? '1' : '0');
  465. getCheckStatus(currentComputeDate);
  466. getJiezhuanStatusHandle();
  467. }
  468. }, [currentComputeDate]);
  469. useEffect(() => {
  470. //tableRef.current?.reload();
  471. if (currentComputeDate && currentSelectedTreeNode) {
  472. if (!ifCheckPage) {
  473. getCurrentCommitStatus();
  474. }
  475. if (ifCheckPage) {
  476. getCurrentUnitCheckStatus();
  477. }
  478. getTableData({});
  479. }
  480. }, [currentSelectedTreeNode, currentComputeDate]);
  481. //console.log({inputsRef,inputsRefKeys});
  482. useEffect(() => {
  483. //初始化左侧树结构数据后
  484. if (treeData?.length > 0) {
  485. if (!currentSelectedTreeNode) {
  486. if (treeData[0].child && treeData[0].child.length > 0) {
  487. const [node, nodeParent] = getDeepestTreeData(treeData[0], 'child');
  488. set_currentSelectedTreeNode(node);
  489. setExpandedKeys([nodeParent.code]);
  490. getCurrentCommitStatus();
  491. }
  492. }
  493. }
  494. }, [treeData]);
  495. useEffect(() => {
  496. if (location.pathname == "/secondaryDistribute/secondaryDitriCheck") {
  497. set_ifCheckPage(true);
  498. } else { set_ifCheckPage(false); }
  499. }, [location])
  500. useEffect(() => {
  501. if (needSaveData) {
  502. buildTableData(needSaveData, inputsRefKeys);
  503. }
  504. }, [needSaveData]);
  505. useEffect(() => {
  506. if (dataSource && Object.keys(inputsRef.current).length > 0) {
  507. currentInputRefKeys && inputsRef.current[currentInputRefKeys].focus();
  508. }
  509. }, [dataSource])
  510. useEffect(() => {
  511. if (auditType == '1') {
  512. //当审核中时,禁掉所有操作
  513. set_commitStatus('1');
  514. }
  515. }, [auditType]);
  516. useEffect(() => {
  517. let keys: string[] = [];
  518. if (ifEditMode && needSaveData) {
  519. //获取所有输入框的ref key
  520. const { userList } = needSaveData;
  521. userList.forEach((a: any) => {
  522. a.itemValue.forEach((b: any) => {
  523. keys.push(`${a.account}-${b.code}`)
  524. })
  525. });
  526. set_inputsRefKeys(keys);
  527. }
  528. if (needSaveData) {
  529. if (ifEditMode) {
  530. gennerateColumns(needSaveData, keys)
  531. } else {
  532. gennerateColumns(needSaveData)
  533. }
  534. }
  535. if (!ifEditMode) {
  536. set_currentInputRefKeys(undefined);
  537. getTableData({}); //重新拉数据
  538. }
  539. }, [ifEditMode]);
  540. useEffect(() => {
  541. if (ifEditMode && Object.keys(inputsRef.current).length > 0 && inputsRefKeys.length > 0) {
  542. inputsRef.current[`${inputsRefKeys[0]}`].focus();
  543. set_currentInputRefKeys(inputsRefKeys[0]);
  544. }
  545. }, [inputsRef, inputsRefKeys]);
  546. useEffect(()=>{
  547. changeTreeDataFilter(currentTreeDataFilter);
  548. },[treeDataDefault])
  549. useEffect(() => {
  550. set_tableColumn(column as ProColumns[]);
  551. getCurrentComputeDate();
  552. window.addEventListener('resize', (e) => handleResize(e)) //监听窗口大小改变
  553. doResize();
  554. return () => {
  555. window.removeEventListener('resize', (e) => handleResize(e))
  556. }
  557. }, []);
  558. return (
  559. <div className='SecondaryDitriComputed'>
  560. {
  561. treeFilterVisible && (
  562. <div className='selecterList'>
  563. <div onClick={() => changeTreeDataFilter({ name: '全部单元', code: 0 })} className={currentTreeDataFilter.code == 0 ? 'list on' : 'list'}>全部单元</div>
  564. <div onClick={() => changeTreeDataFilter({ name: ifCheckPage ? '未审核' : '未提交', code: 1 })} className={currentTreeDataFilter.code == 1 ? 'list on' : 'list'}>{ifCheckPage ? '未审核' : '未提交'}</div>
  565. <div onClick={() => changeTreeDataFilter({ name: ifCheckPage ? '已审核' : '已提交', code: 2 })} className={currentTreeDataFilter.code == 2 ? 'list on' : 'list'}>{ifCheckPage ? '已审核' : '已提交'}</div>
  566. </div>
  567. )
  568. }
  569. <div className='leftTree'>
  570. <div className='search'>
  571. <Input
  572. className='searchInput'
  573. placeholder="请输入类目名称"
  574. size='small'
  575. allowClear
  576. style={{ width: 158 }}
  577. onChange={onTreeSearchKeyChange}
  578. suffix={
  579. <SearchIcon type='iconsousuo' />
  580. }
  581. />
  582. <Tooltip placement="top" title={currentTreeDataFilter.name}>
  583. <div className={currentTreeDataFilter.code == 0 ? 'filter' : currentTreeDataFilter.code == 1 ? 'filter orange' : 'filter blue'} onClick={() => set_treeFilterVisible(true)}></div>
  584. </Tooltip>
  585. </div>
  586. {
  587. treeData && treeData.length > 0 && currentSelectedTreeNode && (
  588. <DirectoryTree
  589. fieldNames={{ title: 'name', key: 'code', children: 'child' }}
  590. rootStyle={{ height: '100%', paddingBottom: 50, overflowY: 'scroll', overflowX: 'hidden' }}
  591. onSelect={onSelect}
  592. onExpand={onExpand}
  593. expandedKeys={expandedKeys}
  594. autoExpandParent={autoExpandParent}
  595. selectedKeys={[currentSelectedTreeNode.code]}
  596. blockNode={true}
  597. icon={() => null}
  598. titleRender={
  599. (nodeData: any) => {
  600. const strTitle = nodeData.name as string;
  601. const index = strTitle.indexOf(searchValue);
  602. const beforeStr = strTitle.substring(0, index);
  603. const afterStr = strTitle.slice(index + searchValue.length);
  604. const title =
  605. index > -1 ? (
  606. <span>
  607. {beforeStr}
  608. <span className="site-tree-search-value" style={{ color: '#3377ff', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{searchValue}</span>
  609. {afterStr}
  610. </span>
  611. ) : (
  612. <span className='strTitle'>{strTitle}</span>
  613. );
  614. return <div style={{
  615. display: 'flex', flexDirection: 'row',
  616. width: '100%',
  617. justifyContent: 'space-between', alignItems: 'center', height: 32,
  618. borderRadius: '4px',
  619. overflow: 'hidden',
  620. color: '#17181A',
  621. textOverflow: 'ellipsis',
  622. whiteSpace: 'nowrap'
  623. }}>
  624. {title}
  625. {!nodeData.map && <span className={nodeData.unitType ? 'point lastChild' : 'point'}></span>}
  626. </div>
  627. }
  628. }
  629. defaultSelectedKeys={[treeData[0].child[0].code]}
  630. treeData={treeData as unknown as DataNode[]}
  631. // treeData={treeDataNew}
  632. switcherIcon={(props: any) => {
  633. const { expanded } = props;
  634. return !expanded ? <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={expandedIcon} /> : <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={closeIcon} />
  635. }}
  636. />
  637. )
  638. }
  639. </div>
  640. {/* <div style={{width:16,height:'92vh',background:'#F5F7FA'}}></div> */}
  641. <div className='rightContent'>
  642. <BMSPagecontainer title={false} ghost>
  643. <div className='tabContent'>
  644. <div className='tableToolbar'>
  645. {currentComputeDate && (<div className='search'>
  646. <span>核算年月:</span>
  647. <DatePicker
  648. onChange={(data, dateString) => {
  649. set_currentComputeDate(dateString);
  650. }}
  651. allowClear={false}
  652. picker='month'
  653. locale={locale}
  654. defaultValue={moment(currentComputeDate,'YYYY-MM')}
  655. format='YYYY-MM' placeholder="请选择核算年月" />
  656. </div>)}
  657. <div className='btnGroupWrap'>
  658. {
  659. (!ifCheckPage&&!ifBanAllAction) && (
  660. //计算界面
  661. <>
  662. <Popover open={ifShowTip} content={auditType == '1' ? '当前处于审核中,无法操作!' : '当前处于提交中,无法操作!'} >
  663. <div className={commitStatus != '0' || auditType == '1' ? 'btnGroup disabled' : 'btnGroup'}
  664. /**
  665. * 当审核中,三个操作按钮都不可点击
  666. * 当非审核中,生成和添加不可操作
  667. */
  668. onMouseEnter={() => auditType == '0' ? commitStatus == '1' ? set_ifShowTip(true) : set_ifShowTip(false) : set_ifShowTip(true)}
  669. onMouseLeave={() => set_ifShowTip(false)}
  670. >
  671. {(!ifEditMode&&userFunctionInThispage && (userFunctionInThispage.findIndex((a: { code: string, name: string }) => a.code == 'calculate') != -1)) && <span className='compute cancel' onClick={commitStatus == '0' && auditType != '1' ? () => computeHandle() : () => { }}>计算</span>}
  672. {!ifEditMode && <span className='cancel' onClick={commitStatus == '0' && auditType != '1' ? () => set_ifEditMode(true) : () => { }}>编辑</span>}
  673. {ifEditMode && <span className='cancel' onClick={commitStatus == '0' ? () => set_ifEditMode(false) : () => { }}>取消</span>}
  674. {ifEditMode && <span className='editBtn' onClick={commitStatus == '0' && auditType != '1' ? () => saveHandle() : () => { }}>保存</span>}
  675. </div>
  676. </Popover>
  677. {!ifEditMode && <div key="" className={auditType == '1' ? 'commit disabled' : 'commit'} onClick={() => auditType == '0' ? commitBtnhandle() : () => { }}>{commitStatus == '1' ? '取消提交' : '提交'}</div>}
  678. </>
  679. )
  680. }
  681. {
  682. !ifBanAllAction&&ifCheckPage && userFunctionInThispage && (userFunctionInThispage.findIndex((a: { code: string, name: string }) => a.code == 'audit') != -1) && (
  683. <>
  684. <div className={'commit gray'} onClick={() => commitBtnhandle(1)}>{currentUnitAuditType == '1' ? '取消审核单个' : '审核单个'}</div>
  685. <div className={'commit'} onClick={() => commitBtnhandle(2)}>{auditType == '1' ? '取消审核全部' : '审核全部'}</div>
  686. </>
  687. )
  688. }
  689. </div>
  690. </div>
  691. <div className='info'>
  692. <span className='total'>可分配总额: <i>{pageData.total}</i></span>
  693. <span className='compelted'>已分配总额: <i>{pageData.completedTotal}</i></span>
  694. <span className='left'>剩余分配总额: <i>{pageData.leftTotal}</i></span>
  695. </div>
  696. {currentSelectedTreeNode && <BMSTable pagination={false} actionRef={tableRef} rowKey='id'
  697. scroll={{ x: 120 * tableColumn.length, y: tableH }}
  698. columns={[...tableColumn]} dataSource={dataSource}
  699. summary={(pageData) => {
  700. const Caculate = ({ colData }: { colData: any }) => {
  701. const { dataIndex } = colData;
  702. const total = pageData.reduce((prev, cur) => {
  703. return prev + cur[`${dataIndex}`]
  704. }, 0);
  705. if (dataIndex != 'account' && dataIndex != 'name' && dataIndex != 'submitName') {
  706. return (
  707. <span>{formatMoneyNumber(Number(total.toFixed(2)))}</span>
  708. )
  709. }
  710. if (dataIndex == 'name') {
  711. return <span>合计</span>
  712. }
  713. return <></>
  714. }
  715. return (
  716. <Table.Summary fixed>
  717. <Table.Summary.Row>
  718. {
  719. tableColumn.map((item, index) => {
  720. return (
  721. <Table.Summary.Cell key={index} index={index} align='left' rowSpan={1} >
  722. <Caculate colData={item} />
  723. </Table.Summary.Cell >
  724. )
  725. })
  726. }
  727. </Table.Summary.Row>
  728. </Table.Summary>
  729. );
  730. }}
  731. />}
  732. </div>
  733. </BMSPagecontainer>
  734. </div >
  735. </div >
  736. );
  737. };
  738. export default SecondaryDitriComputed;