123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- import React, { useEffect, useRef, useState } from 'react';
- import { BMSTable } from '@/components/BMSTable';
- import { createFromIconfontCN } from '@ant-design/icons';
- import { ProColumns } from '@ant-design/pro-components';
- import { Tabs, InputNumber, message } from 'antd';
- import { debounce } from 'lodash';
- import { Key } from 'react';
- import { getUnitRetainListReq, getUnitTypes, saveUnitRetainReq } from '../../service';
- import './style.less';
- import TableSelecter from './tableSelector';
- const IconFont = createFromIconfontCN({
- scriptUrl: '',
- });
- export const Distribute = ({ computeDate }: { computeDate: string }) => {
- const [tabs, set_tabs] = useState<any[]>([]);
- const [editable, set_editable] = useState(false);
- const [dataSource, set_dataSource] = useState<any[]>([]);
- const [currentTab, set_currentTab] = useState<undefined | string>(undefined);
- const [tableColumns, set_tableColumns] = useState<ProColumns[]>([]);
- const [titles, set_titles] = useState<any[]>([]);
- const [tableSelecterVisible, set_tableSelecterVisible] = useState(false);
- const [currentBlock, set_currentBlock] = useState<any>(undefined);
- const [inputNum, set_inputNum] = useState(0);
- const [currentEdit, set_currentEdit] = useState({ colCode: '', num: 0, rowCode: '' });
- const [slectedRows, set_slectedRows] = useState<any[]>([]);
- const [editMode, set_editMode] = useState(false);
- const wrapContainerRef = useRef<HTMLDivElement>(null);
- const tableBodyRef = useRef<HTMLDivElement>(null);
- const getTab = async () => {
- const resp = await getUnitTypes();
- if (resp) {
- const arr = resp.list.map((a: any, index: number) => ({
- label: a.name,
- key: a.code,
- }));
- set_tabs([...arr]);
- if (arr.length > 0) set_currentTab(arr[0].key);
- }
- };
- const onTabChange = (tabKey: string) => {
- set_currentTab(tabKey);
- };
- const getTableData = async (unitType: string) => {
- if (!unitType) return;
- const resp = await getUnitRetainListReq(computeDate, unitType);
- if (resp) {
- const { title = [], remainData = [], data = [] } = resp;
- set_titles(
- title.map((a: any) => {
- const value = remainData.filter((b: any) => a.code == b.code)[0].value;
- return {
- ...a,
- value,
- };
- })
- );
- const arr = title.map((a: any) => ({
- title: a.name,
- dataIndex: `${a.code}`,
- key: `${a.code}`,
- width: 230,
- renderText(num: number, record: any) {
- const InputComponent = () => {
- const [inputNum, set_inputNum] = useState(0);
- const handleChange = (num: number | null) => {
- set_inputNum(num ? num : 0);
- };
- const onBlurhandle = () => {
- set_currentEdit({ colCode: a.code, num: inputNum, rowCode: record.unitCode });
- };
- return (
- <InputNumber
- style={{ width: '100%' }}
- disabled={!editMode || a.code == 'totalBonus'}
- precision={2}
- min={0}
- defaultValue={num}
- onBlur={onBlurhandle}
- onChange={handleChange}
- />
- );
- };
- return <InputComponent />;
- },
- }));
- set_tableColumns([
- {
- title: '核算单元名称',
- dataIndex: 'unitName',
- key: 'unitName',
- width: 182,
- ellipsis: true,
- fixed: 'left',
- },
- ...arr,
- ]);
- const tableData = data.map((a: any) => {
- let obj: any = {};
- let totalCount = 0;
- title.forEach((b: any) => {
- const { data: rowData } = a;
- const needItem = rowData.filter((c: any) => c.code == b.code);
- obj[`${b.code}`] = needItem.length > 0 ? needItem[0].value : 0;
- if (b.code != 'totalBonus') {
- totalCount = totalCount + (needItem.length > 0 ? needItem[0].value : 0);
- }
- });
- return {
- ...a,
- ...obj,
- totalBonus: totalCount,
- };
- });
- set_dataSource([...tableData]);
- }
- };
- const tableSelecterCommit = (keys: Key[], rows: any[]) => {
- set_slectedRows([...slectedRows, ...rows]);
- if (currentBlock.code == 'totalBonus') {
- const newTitles = titles.map((a) => {
- if (a.code == currentBlock.code) {
- return {
- ...a,
- value: rows.reduce((prev: number, cur: any) => prev + cur.retainBonus, 0),
- };
- } else {
- const needArr = rows.filter((b) => b.retainCode == a.code);
- return {
- ...a,
- value: needArr.length > 0 ? needArr.reduce((prev: number, cur: any) => prev + cur.retainBonus, 0) : 0,
- };
- }
- });
- set_titles([...newTitles]);
- } else {
- const amount = rows.reduce((prev: number, cur: any) => prev + cur.retainBonus, 0);
- const newTitles = titles.map((a) => {
- if (a.code == currentBlock.code) {
- return {
- ...a,
- value: a.value + amount,
- };
- } else {
- return a;
- }
- });
- const titlesvalueCount = newTitles.reduce((prev: number, cur: any) => {
- if (cur.code != 'totalBonus') {
- return prev + cur.value;
- } else {
- return prev;
- }
- }, 0);
- set_titles(
- newTitles.map((a: any) => {
- if (a.code == 'totalBonus') {
- return { ...a, value: titlesvalueCount };
- } else {
- return a;
- }
- })
- );
- }
- set_tableSelecterVisible(false);
- };
- const saveHandle = async () => {
- const reaultData = dataSource.map((a) => {
- return {
- unitCode: a.unitCode,
- unitName: a.unitName,
- data: titles.map((b) => ({ code: b.code, value: a[`${b.code}`] })),
- };
- });
- const arr = titles.map((a) => {
- const ids = slectedRows.filter((b) => b.retainCode == a.code).map((c) => c.id);
- return {
- retainCode: a.code,
- retainIds: [...new Set(ids)],
- };
- });
- const result = {
- data: reaultData,
- remainData: titles.map((a) => ({ code: a.code, value: a.value })),
- historyRetain: arr,
- };
- const resp = await saveUnitRetainReq(result);
- if (resp) {
- message.success('保存成功!');
- set_editMode(false);
- set_slectedRows([]);
- }
- };
- useEffect(() => {
- getTableData(currentTab as string);
- }, [editMode]);
- useEffect(() => {
- // 更新 titles
- const newTitles = titles.map((b) => {
- if (b.code === currentEdit.colCode) {
- return { ...b, value: b.value - currentEdit.num };
- } else {
- return b;
- }
- });
- const titlesvalueCount = newTitles.reduce((prev: number, cur: any) => {
- if (cur.code != 'totalBonus') {
- return prev + cur.value;
- } else {
- return prev;
- }
- }, 0);
- set_titles(
- newTitles.map((a: any) => {
- if (a.code == 'totalBonus') {
- return { ...a, value: titlesvalueCount };
- } else {
- return a;
- }
- })
- );
- // 基于更新后的 titles 同时更新 dataSource
- const updatedDataSource = dataSource.map((item) => {
- if (item.unitCode == currentEdit.rowCode) {
- let total = 0;
- titles.forEach((a) => {
- if (a.code != 'totalBonus') {
- if (a.code == currentEdit.colCode) {
- total = total + currentEdit.num;
- } else {
- total = total + item[`${a.code}`];
- }
- }
- });
- return { ...item, [`${currentEdit.colCode}`]: currentEdit.num, totalBonus: total };
- } else {
- return item;
- }
- });
- set_dataSource(updatedDataSource);
- }, [currentEdit]);
- useEffect(() => {
- if (currentTab) {
- getTableData(currentTab);
- }
- }, [currentTab]);
- useEffect(() => {
- getTab();
- }, []);
- useEffect(() => {
- if (titles.length > 0) {
- const handleScroll = () => {
- if (wrapContainerRef.current && tableBody) {
- wrapContainerRef.current.scrollLeft = tableBody.scrollLeft;
- }
- };
- const tableBody = document.querySelector('.bms-ant-table-body') as HTMLElement;
- // 获取 bms-ant-table-cell 元素
- const td = document.querySelector('.bms-ant-table-cell') as HTMLElement;
- const fixedTd = document.querySelector('.bms-ant-table-cell-fix-left') as HTMLElement;
- if (td) {
- // 获取元素的样式
- const style = getComputedStyle(td);
- // 获取元素的宽度,包含 padding 和 border
- const paddingLeft = parseFloat(style.paddingLeft);
- const paddingRight = parseFloat(style.paddingRight);
- const borderLeftWidth = parseFloat(style.borderLeftWidth);
- const borderRightWidth = parseFloat(style.borderRightWidth);
- const tdWidth = td.clientWidth + paddingLeft + paddingRight + borderLeftWidth + borderRightWidth;
- // console.log('bms-ant-table-cell 的实际宽度(包含 padding 和 border):', tdWidth);
- } else {
- // console.log('没有找到 .bms-ant-table-cell 元素');
- }
- if (fixedTd) {
- // 获取元素的样式
- const style = getComputedStyle(fixedTd);
- // 获取元素的宽度,包含 padding 和 border
- const paddingLeft = parseFloat(style.paddingLeft);
- const paddingRight = parseFloat(style.paddingRight);
- const borderLeftWidth = parseFloat(style.borderLeftWidth);
- const borderRightWidth = parseFloat(style.borderRightWidth);
- const fixedTdWidth = fixedTd.clientWidth + paddingLeft + paddingRight + borderLeftWidth + borderRightWidth;
- // console.log('bms-ant-table-cell-fix-left 的实际宽度(包含 padding 和 border):', fixedTdWidth);
- } else {
- // console.log('没有找到 .bms-ant-table-cell-fix-left 元素');
- }
- if (tableBody) {
- tableBody.addEventListener('scroll', handleScroll);
- }
- // 清理函数,用于移除事件监听器
- return () => {
- if (tableBody) {
- tableBody.removeEventListener('scroll', handleScroll);
- }
- };
- }
- }, [titles]);
- return (
- <div className="Distribute">
- <TableSelecter
- onVisibleChange={(bool) => set_tableSelecterVisible(bool)}
- title="添加保留考核奖金"
- rowKey={'id'}
- defaultSelectedKeys={slectedRows.map((a: any) => a.id)}
- record={{ ...currentBlock, currentTab }}
- open={tableSelecterVisible}
- onFinish={tableSelecterCommit}
- />
- <div className="Distribute_header">
- <span className="title">保留奖金分配</span>
- {!editMode && (
- <span className="editBtn" onClick={() => set_editMode(true)}>
- <IconFont style={{ color: '#3376FE', cursor: 'pointer', marginRight: 4, fontSize: 16 }} type={'iconbianji'} />
- 开始分配
- </span>
- )}
- {editMode && (
- <div className="saveBtn">
- <span className="cancel" onClick={() => set_editMode(false)}>
- 取消
- </span>
- <span className="save" onClick={() => saveHandle()}>
- 保存
- </span>
- </div>
- )}
- </div>
- {tabs.length > 0 && <Tabs defaultActiveKey={currentTab} onChange={onTabChange} items={tabs} />}
- <div className="rowOne">
- <div className="blockHeader">
- <img src={require('../../../../../../static/distribute.png')} alt="" />
- <div className="detail">
- <span className="name">可分配额</span>
- <span className="sub">对总额进行分配</span>
- </div>
- </div>
- <div className="wrap" ref={wrapContainerRef}>
- {titles.map((a, index) => (
- <div className="block" key={index}>
- <div className="left">
- <span className="label">{a.name}(元)</span>
- <span className="value">{a.value}</span>
- </div>
- <div className="icon">
- <IconFont
- style={{ color: '#17181A', cursor: 'pointer' }}
- type={'icon-zhuijia'}
- onClick={() => {
- set_currentBlock(a);
- set_tableSelecterVisible(true);
- }}
- />
- </div>
- </div>
- ))}
- </div>
- </div>
- {titles.length > 0 && (
- <div className="table-body">
- <BMSTable
- className="Distribute_table"
- dataSource={dataSource}
- scroll={{ x: titles.length * 220 + 192, y: editMode ? 440 : 470 }}
- pagination={false}
- rowKey="unitCode"
- columns={[...tableColumns]}
- />
- </div>
- )}
- </div>
- );
- };
|