|
@@ -0,0 +1,962 @@
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * @Author: code4eat awesomedema@gmail.com
|
|
|
+ * @Date: 2022-12-16 09:42:52
|
|
|
+ * @LastEditors: code4eat awesomedema@gmail.com
|
|
|
+ * @LastEditTime: 2023-08-02 11:01:20
|
|
|
+ * @FilePath: /BudgetManaSystem/src/pages/budgetMana/monthlySet/index.tsx
|
|
|
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+import BMSPagecontainer from '@/components/BMSPageContainer';
|
|
|
+
|
|
|
+import { useEffect, useRef, useState } from 'react';
|
|
|
+import './style.less';
|
|
|
+
|
|
|
+import { TreeProps, Input, Modal, message, Popover, Table, Switch, Tooltip } from 'antd';
|
|
|
+import { DataNode } from 'antd/es/tree';
|
|
|
+
|
|
|
+import expandedIcon from '../../../../static/treenode_open.png';
|
|
|
+import closeIcon from '../../../../static/treenode_collapse.png';
|
|
|
+import { BMSTable } from '@/components/BMSTable';
|
|
|
+import { ActionType, ModalForm, ProColumns, ProFormDatePicker, ProFormDigit, ProFormInstance, ProFormSelect, ProFormText } from '@ant-design/pro-components';
|
|
|
+import { createFromIconfontCN } from '@ant-design/icons';
|
|
|
+import { checkCurrentRequest, checkRequest, commitRequest, getCurrentCheckStatusReq, getCurrentCommitStatusReq, getCurrentUnitCheckStatusReq, getSecondaryDistriComputeTableData, getTreeData, getTreeDataRespType, save } from './service';
|
|
|
+import FormItem from 'antd/es/form/FormItem';
|
|
|
+
|
|
|
+import { getComputeDate } from '@/pages/Home/service';
|
|
|
+
|
|
|
+import React from 'react';
|
|
|
+import DirectoryTree from 'antd/es/tree/DirectoryTree';
|
|
|
+import { getDeepestTreeData } from '@/utils/tooljs';
|
|
|
+
|
|
|
+import { getCurrentCheckStatus } from '@/services/auth';
|
|
|
+
|
|
|
+import { useLocation } from '@umijs/max';
|
|
|
+import { useAccess } from '@umijs/max';
|
|
|
+
|
|
|
+import { getParamsData } from '@/pages/setting/baseSetting/paramsMana/service';
|
|
|
+
|
|
|
+import 'moment/locale/zh-cn';
|
|
|
+import locale from 'antd/es/date-picker/locale/zh_CN';
|
|
|
+import moment from 'moment';
|
|
|
+import { getJiezhuanStatus } from '@/pages/budgetMana/monthlySet/service';
|
|
|
+import '../../../utils/zhongtaiA';
|
|
|
+import BMSUpload from '@/components/BMSUpload';
|
|
|
+
|
|
|
+
|
|
|
+const SearchIcon = createFromIconfontCN({
|
|
|
+ scriptUrl: '',
|
|
|
+});
|
|
|
+
|
|
|
+const IconFont = createFromIconfontCN({
|
|
|
+ scriptUrl: '',
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+export type TableListItem = {
|
|
|
+ key: number;
|
|
|
+ name: string;
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+const UnitCheckProjectScore: React.FC = () => {
|
|
|
+ const location = useLocation();
|
|
|
+ const access = useAccess();
|
|
|
+ const userFunctionInThispage = access.whatCanIDoInThisPage(location.pathname);
|
|
|
+ const [ifCheckPage, set_ifCheckPage] = useState(false); //是否为二次分配审核页面
|
|
|
+ const [treeData, set_treeData] = useState<getTreeDataRespType[]>([]);
|
|
|
+ const [treeDataDefault, set_treeDataDefault] = useState<getTreeDataRespType[]>([]);
|
|
|
+ const [tableColumn, set_tableColumn] = useState<ProColumns[]>([]);
|
|
|
+ const [currentSelectedTreeNode, set_currentSelectedTreeNode] = useState<any | undefined>();
|
|
|
+
|
|
|
+ const [currentComputeDate, set_currentComputeDate] = useState<string | undefined>();
|
|
|
+
|
|
|
+ const [ifShowTip, set_ifShowTip] = useState(false);
|
|
|
+
|
|
|
+ const [commitStatus, set_commitStatus] = useState('0'); //提交状态
|
|
|
+
|
|
|
+ const [empFilterParams, set_empFilterParams] = useState<any | undefined>(undefined);
|
|
|
+
|
|
|
+ const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
|
|
|
+ const [searchValue, setSearchValue] = useState('');
|
|
|
+ const [autoExpandParent, setAutoExpandParent] = useState(true);
|
|
|
+
|
|
|
+ const [ifEditMode, set_ifEditMode] = useState(false);
|
|
|
+
|
|
|
+ const [auditType, set_auditType] = useState('0'); //审核状态
|
|
|
+
|
|
|
+ const [currentUnitAuditType, set_currentUnitAuditType] = useState('0'); //当前单元审核状态
|
|
|
+
|
|
|
+ const tableRef = useRef<ActionType>();
|
|
|
+
|
|
|
+ const [needSaveData, set_needSaveData] = useState<any | undefined>(undefined);
|
|
|
+
|
|
|
+ const [inputsRefKeys, set_inputsRefKeys] = useState<string[]>([]);
|
|
|
+
|
|
|
+ const inputsRef = useRef<{ [key: string]: any }>({});
|
|
|
+
|
|
|
+ const [pageData, set_pageData] = useState({ total: 0, completedTotal: 0, leftTotal: 0 });
|
|
|
+
|
|
|
+ const [dataSource, set_dataSource] = useState([]);
|
|
|
+
|
|
|
+ const [currentInputRefKeys, set_currentInputRefKeys] = useState<string | undefined>(undefined);
|
|
|
+ const [tableH, set_tableH] = useState(0);
|
|
|
+ const [currentTreeDataFilter, set_currentTreeDataFilter] = useState({ name: '全部单元', code: 0 });
|
|
|
+ const [treeFilterVisible, set_treeFilterVisible] = useState(false);
|
|
|
+
|
|
|
+ const [ifBanAllAction, set_ifBanAllAction] = useState(true); //是否掩藏所有操作
|
|
|
+
|
|
|
+
|
|
|
+ const column: ProColumns[] = [
|
|
|
+ {
|
|
|
+ title: '姓名',
|
|
|
+ width: 140,
|
|
|
+ fixed: 'left',
|
|
|
+ dataIndex: 'name',
|
|
|
+ renderText(text, record, index, action) {
|
|
|
+ return `${record.name}(${record.account})`
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ];
|
|
|
+
|
|
|
+
|
|
|
+ const onSelect: TreeProps['onSelect'] = (selectedKeys, info: any) => {
|
|
|
+ // console.log('selected', selectedKeys, info);
|
|
|
+ if (!ifEditMode) {
|
|
|
+ //编辑时,需要先保存后切换
|
|
|
+ const { node } = info;
|
|
|
+ if (!node.child) {
|
|
|
+ set_currentSelectedTreeNode(node);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '提示', content: '当前存在编辑未保存,请先保存!', okText: '确定',
|
|
|
+ cancelText: '取消',
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ const downloadTemplate = ()=>{
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const importData = () => {
|
|
|
+
|
|
|
+ return (
|
|
|
+ <ModalForm
|
|
|
+ width={360}
|
|
|
+ title={`导入${name}数据`}
|
|
|
+ trigger={
|
|
|
+ <span key="3" className='compute cancel'>导入</span>
|
|
|
+ }
|
|
|
+ submitter={{
|
|
|
+ render: (props, defaultDoms) => {
|
|
|
+ const needBtn = defaultDoms.filter((b) => {
|
|
|
+ return b.key != 'rest'
|
|
|
+ })
|
|
|
+ return [
|
|
|
+ // <Button
|
|
|
+ // key="ok"
|
|
|
+ // onClick={auditType == '0' ? () => downloadTemplate(index) : () => { }}
|
|
|
+ // >
|
|
|
+ // 下载模板
|
|
|
+ // </Button>,
|
|
|
+ ...needBtn,
|
|
|
+ ];
|
|
|
+ },
|
|
|
+ }}
|
|
|
+ onFinish={async (values) => {
|
|
|
+ // console.log({values});
|
|
|
+ const { importFile: { fileList } } = values;
|
|
|
+
|
|
|
+ let formData = new FormData();
|
|
|
+ // if (index == 7) {
|
|
|
+ // formData.append('file', fileList[0].originFileObj);
|
|
|
+ // formData.append('computeDate', currentComputeDate as string);
|
|
|
+ // formData.append('unitCode', currentSelectedTreeNode.code);
|
|
|
+ // } else {
|
|
|
+ // formData.append('file', fileList[0].originFileObj);
|
|
|
+ // formData.append('computeDate', currentComputeDate as string);
|
|
|
+ // formData.append('groupId', currentSelectedManaGroup?.id as any);
|
|
|
+ // }
|
|
|
+
|
|
|
+
|
|
|
+ // const resp = await importMonthlyperformanceRelaFiles(index, formData);
|
|
|
+
|
|
|
+ // if (resp) {
|
|
|
+ // tableRef.current?.reload();
|
|
|
+ // return true;
|
|
|
+ // }
|
|
|
+
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <FormItem name={'importFile'}>
|
|
|
+ <BMSUpload downloadTemplateFile={()=>auditType == '0' ? downloadTemplate() : () => { }} />
|
|
|
+ </FormItem>
|
|
|
+
|
|
|
+ </ModalForm>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ const getCurrentComputeDate = async () => {
|
|
|
+ const resp = await getComputeDate();
|
|
|
+ set_currentComputeDate(resp);
|
|
|
+ }
|
|
|
+
|
|
|
+ const getCheckStatus = async (computeDate: string) => {
|
|
|
+
|
|
|
+ const resp = await getCurrentCheckStatusReq(computeDate);
|
|
|
+ set_auditType(`${resp}`); //0 未审核 1 已审核
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const getCurrentUnitCheckStatus = async () => {
|
|
|
+ if (currentSelectedTreeNode) {
|
|
|
+ const resp = await getCurrentUnitCheckStatusReq(currentComputeDate as string, currentSelectedTreeNode.code);
|
|
|
+ set_currentUnitAuditType(`${resp}`); //0 未审核 1 已审核
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const getCurrentCommitStatus = async () => {
|
|
|
+ if (currentSelectedTreeNode) {
|
|
|
+ const resp = await getCurrentCommitStatusReq({
|
|
|
+ computeDate: currentComputeDate as string,
|
|
|
+ unitCode: currentSelectedTreeNode.code
|
|
|
+ });
|
|
|
+ set_commitStatus(`${resp}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const gennerateColumns = (data: { title: any; userList: any; }, inputsRefKeys?: string[]) => {
|
|
|
+ const { title } = data;
|
|
|
+ const _columns = title.map((item: any, index: number) => {
|
|
|
+ return {
|
|
|
+ title: item.name,
|
|
|
+ dataIndex: `${item.code}`,
|
|
|
+ width: 120,
|
|
|
+ renderText: (_: any, record: any) => {
|
|
|
+ if (ifEditMode) {
|
|
|
+
|
|
|
+ let _val = _;
|
|
|
+
|
|
|
+ if(true){
|
|
|
+
|
|
|
+ return <ProFormSelect
|
|
|
+ request={async ()=>{
|
|
|
+ return []
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ }
|
|
|
+
|
|
|
+ return <ProFormDigit noStyle min={-1000000000} fieldProps={{
|
|
|
+ ref: ref => {
|
|
|
+ inputsRef.current[`${record.account}-${item.code}`] = ref;
|
|
|
+ //console.log({ref});
|
|
|
+ },
|
|
|
+ onBlur: () => {
|
|
|
+ const updatedUserList = needSaveData.userList.map((a: any) => {
|
|
|
+ if (a.account == record.account) {
|
|
|
+ const arr = a.itemValue.map((b: any) => {
|
|
|
+ if (b.code == item.code) {
|
|
|
+ return { ...b, value: _val ? _val : 0 } //value有为undefined的可能
|
|
|
+ } else {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return { ...a, itemValue: arr }
|
|
|
+ } else {
|
|
|
+ return a
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ set_needSaveData({ ...needSaveData, userList: updatedUserList })
|
|
|
+ },
|
|
|
+ onChange(value) {
|
|
|
+ _val = value ? value : 0;
|
|
|
+ },
|
|
|
+ onPressEnter: (event: any) => {
|
|
|
+ if (event.code === 'Enter') {
|
|
|
+ event.preventDefault();
|
|
|
+
|
|
|
+ const value = event.target.value ? Number(event.target.value) : 0;
|
|
|
+ const updatedUserList = needSaveData.userList.map((a: any) => {
|
|
|
+ if (a.account == record.account) {
|
|
|
+ const arr = a.itemValue.map((b: any) => {
|
|
|
+ if (b.code == item.code) {
|
|
|
+ return { ...b, value: value ? value : 0 } //value有为undefined的可能
|
|
|
+ } else {
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return { ...a, itemValue: arr }
|
|
|
+ } else {
|
|
|
+ return a
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ set_needSaveData({ ...needSaveData, userList: updatedUserList });
|
|
|
+
|
|
|
+ const index = inputsRefKeys ? inputsRefKeys.findIndex(a => a == `${record.account}-${item.code}`) : -1;
|
|
|
+ //console.log({index,input:inputsRef.current,inputsRefKeys});
|
|
|
+ const nextInput = inputsRefKeys ? inputsRef.current[inputsRefKeys[index + 1]] : null;
|
|
|
+ if (nextInput) {
|
|
|
+ inputsRefKeys && set_currentInputRefKeys(inputsRefKeys[index + 1]);
|
|
|
+ nextInput.focus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onFocus: () => set_currentInputRefKeys(`${record.account}-${item.code}`),
|
|
|
+ defaultValue: _,
|
|
|
+
|
|
|
+ }} width={80} />
|
|
|
+ } else {
|
|
|
+ return <span style={{ display: 'inline-block', width: 80 }}>{_}</span>
|
|
|
+ }
|
|
|
+ },
|
|
|
+ }
|
|
|
+ });
|
|
|
+ set_tableColumn([...column, ..._columns, {
|
|
|
+ title: '总奖金',
|
|
|
+ dataIndex: 'totalScore',
|
|
|
+ width: 120,
|
|
|
+ fixed: 'right',
|
|
|
+ },
|
|
|
+ // {
|
|
|
+ // title: '状态',
|
|
|
+ // width:120,
|
|
|
+ // dataIndex: 'submitName',
|
|
|
+ // renderText(text, record, index, action) {
|
|
|
+ // return record.submit == 1 ? text : <span style={{ color: '#FF8C19' }}>{text}</span>
|
|
|
+ // },
|
|
|
+ // },
|
|
|
+ ]);
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const getTableData = async (params: any) => {
|
|
|
+
|
|
|
+ if (currentSelectedTreeNode && currentComputeDate) {
|
|
|
+ const resp = await getSecondaryDistriComputeTableData({
|
|
|
+ computeDate: currentComputeDate,
|
|
|
+ unitCode: currentSelectedTreeNode.code,
|
|
|
+ ...params,
|
|
|
+ });
|
|
|
+ if (resp) {
|
|
|
+ set_needSaveData(resp);
|
|
|
+ //buildTableData(resp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return []
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ const buildTableData = (resp: any, inputsRefKeys?: string[]) => {
|
|
|
+ const { title, userList } = resp;
|
|
|
+ const _columns = gennerateColumns(resp, inputsRefKeys);
|
|
|
+ const data = userList.map((item: any) => {
|
|
|
+ let total = 0;
|
|
|
+ let rowData: { [key: string]: any } = {};
|
|
|
+
|
|
|
+ item.itemValue.forEach((b: any) => {
|
|
|
+ const needTitle = title.filter((a: any) => a.code == b.code);
|
|
|
+ if (needTitle.length > 0) {
|
|
|
+ rowData[`${needTitle[0].code}`] = b.value
|
|
|
+ }
|
|
|
+ total = total + b.value;
|
|
|
+ });
|
|
|
+
|
|
|
+ return { ...item, ...rowData, id: Math.random(), _columns, totalScore: Number(total.toFixed(2)) }
|
|
|
+ });
|
|
|
+
|
|
|
+ const compeltedTotal = data.reduce((prev: any, cur: any) => prev + cur.totalScore, 0);
|
|
|
+ const leftTotal = resp.totalBonus - compeltedTotal;
|
|
|
+ set_pageData({ ...pageData, total: resp.totalBonus ? resp.totalBonus.toFixed(2) : 0, completedTotal: compeltedTotal.toFixed(2), leftTotal: Number(leftTotal.toFixed(2)) });
|
|
|
+
|
|
|
+ set_dataSource(data)
|
|
|
+ }
|
|
|
+
|
|
|
+ const checkIfCommit = (type: number) => {
|
|
|
+ // type 1 当前 2 全部
|
|
|
+ //检查当前单元是否提交
|
|
|
+ if (type == 1) {
|
|
|
+ //currentUnitAuditType == 1 时是取消操作无需校验
|
|
|
+ return currentUnitAuditType == '1' ? true : currentSelectedTreeNode.map
|
|
|
+ }
|
|
|
+ if (type == 2 && auditType == '0') {
|
|
|
+ //auditType == 1 时是取消操作无需校验
|
|
|
+ interface Node {
|
|
|
+ map: boolean;
|
|
|
+ child?: Node[];
|
|
|
+ }
|
|
|
+
|
|
|
+ function filterNodes(node: Node): Node | null {
|
|
|
+ if (node.map === false && (!node.child || node.child.length === 0)) {
|
|
|
+ return node; // 如果节点map为false并且是叶子节点,返回该节点
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Array.isArray(node.child)) {
|
|
|
+ // 对每个子节点递归执行此过程
|
|
|
+ let child = node.child.map(filterNodes).filter((n): n is Node => n !== null);
|
|
|
+ if (child.length > 0) {
|
|
|
+ // 如果有任何子节点的map属性为false,返回包含这些子节点的新节点
|
|
|
+ return { ...node, child: child };
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果节点map为true,或者所有子节点的map都为true,返回null
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = treeData.map(a => {
|
|
|
+ return filterNodes(a);
|
|
|
+ });
|
|
|
+
|
|
|
+ return result.length == 0
|
|
|
+
|
|
|
+ } else {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const commitBtnhandle = async (type?: number) => {
|
|
|
+ //console.log({type});
|
|
|
+ /**
|
|
|
+ * type 1 单个 2 全部
|
|
|
+ * 提交界面不需要type
|
|
|
+ */
|
|
|
+
|
|
|
+ const handle = async (ifCheckCommit: string) => {
|
|
|
+ if (type == 1) {
|
|
|
+ //审核单个
|
|
|
+ const resp = await checkCurrentRequest({
|
|
|
+ computeDate: currentComputeDate as string,
|
|
|
+ auditType: currentUnitAuditType == '1' ? '0' : '1', //1 审核 0 取消审核
|
|
|
+ unitCode: currentSelectedTreeNode.code,
|
|
|
+ type: ifCheckCommit
|
|
|
+ });
|
|
|
+ if (resp) {
|
|
|
+ message.success('操作成功!');
|
|
|
+ getTreeReqFunc(currentComputeDate as string, ifCheckPage ? '1' : '0');
|
|
|
+ getCurrentUnitCheckStatus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type == 2) {
|
|
|
+ const resp = await checkRequest({
|
|
|
+ computeDate: currentComputeDate as string,
|
|
|
+ auditType: auditType == '1' ? '0' : '1', //1 审核 0 取消审核
|
|
|
+ type: ifCheckCommit
|
|
|
+ });
|
|
|
+ if (resp) {
|
|
|
+ message.success('操作成功!');
|
|
|
+ getTreeReqFunc(currentComputeDate as string, ifCheckPage ? '1' : '0');
|
|
|
+ getCheckStatus(currentComputeDate as string);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ifCheckPage && type) {
|
|
|
+ const checkCondition = await getParamsData({ pageSize: 500 });
|
|
|
+ if (checkCondition) {
|
|
|
+ const needParamsVal = checkCondition.list.filter(a => a.code == '1664510428258115584'); //判断未提交是否可以审核
|
|
|
+ if (needParamsVal.length > 0) {
|
|
|
+ if (needParamsVal[0].value == '0') {
|
|
|
+ handle(needParamsVal[0].value);
|
|
|
+ } else {
|
|
|
+ handle(needParamsVal[0].value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ if (commitStatus == '1') {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '注意',
|
|
|
+ okText: '确定',
|
|
|
+ cancelText: '取消',
|
|
|
+ content: `${commitStatus == '1' ? '取消提交' : '提交'}当前选择的核算单元的数据?`,
|
|
|
+ onOk: async () => {
|
|
|
+ const resp = await commitRequest({
|
|
|
+ computeDate: currentComputeDate as string,
|
|
|
+ unitCode: currentSelectedTreeNode.code,
|
|
|
+ type: commitStatus == '1' ? '0' : '1', //1 提交 0 取消
|
|
|
+ });
|
|
|
+ if (resp) {
|
|
|
+ message.success('提交成功!');
|
|
|
+ getTreeReqFunc(currentComputeDate as string, ifCheckPage ? '1' : '0');
|
|
|
+ getCurrentCommitStatus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+
|
|
|
+ if (pageData.leftTotal != 0) {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '提交时需有单元的剩余分配金额必须是0',
|
|
|
+ okText: '确定',
|
|
|
+ cancelText: '取消',
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '注意',
|
|
|
+ okText: '确定',
|
|
|
+ cancelText: '取消',
|
|
|
+ content: `${commitStatus == '1' ? '取消提交' : '提交'}当前选择的核算单元的数据?`,
|
|
|
+ onOk: async () => {
|
|
|
+ const resp = await commitRequest({
|
|
|
+ computeDate: currentComputeDate as string,
|
|
|
+ unitCode: currentSelectedTreeNode.code,
|
|
|
+ type: commitStatus == '1' ? '0' : '1', //1 提交 0 取消
|
|
|
+ });
|
|
|
+ if (resp) {
|
|
|
+ message.success('提交成功!');
|
|
|
+ getTreeReqFunc(currentComputeDate as string, ifCheckPage ? '1' : '0');
|
|
|
+ getCurrentCommitStatus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ const dataList: any[] = [];
|
|
|
+
|
|
|
+ const getParentKey = (key: React.Key, tree: any[]): React.Key => {
|
|
|
+ let parentKey: React.Key;
|
|
|
+ for (let i = 0; i < tree.length; i++) {
|
|
|
+ const node = tree[i];
|
|
|
+ if (node.child) {
|
|
|
+ if (node.child.some((item: { code: React.Key; }) => item.code === key)) {
|
|
|
+ parentKey = node.code;
|
|
|
+ } else if (getParentKey(key, node.child)) {
|
|
|
+ parentKey = getParentKey(key, node.child);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return parentKey!;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ const onTreeSearchKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
+
|
|
|
+ const { value } = e.target;
|
|
|
+ const newExpandedKeys = dataList
|
|
|
+ .map((item) => {
|
|
|
+ if (item.name.indexOf(value) > -1) {
|
|
|
+ return getParentKey(item.code, treeData);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ });
|
|
|
+
|
|
|
+ const b = newExpandedKeys.filter((item, i, self) => item && self.indexOf(item) === i);
|
|
|
+
|
|
|
+ setExpandedKeys(newExpandedKeys as React.Key[]);
|
|
|
+ setSearchValue(value);
|
|
|
+ setAutoExpandParent(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ //左侧树结构筛选
|
|
|
+ const changeTreeDataFilter = (obj: any) => {
|
|
|
+
|
|
|
+ set_currentTreeDataFilter(obj);
|
|
|
+ set_treeFilterVisible(false);
|
|
|
+
|
|
|
+ interface Node {
|
|
|
+ map: boolean;
|
|
|
+ child?: Node[];
|
|
|
+ }
|
|
|
+
|
|
|
+ function filterNodes(node: Node): Node | null {
|
|
|
+ if (node.map === (obj.code == 1 ? false : true) && (!node.child || node.child.length === 0)) {
|
|
|
+ return node; // 如果节点map为false并且是叶子节点,返回该节点
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Array.isArray(node.child)) {
|
|
|
+ // 对每个子节点递归执行此过程
|
|
|
+ let child = node.child.map(filterNodes).filter((n): n is Node => n !== null);
|
|
|
+ if (child.length > 0) {
|
|
|
+ // 如果有任何子节点的map属性为false,返回包含这些子节点的新节点
|
|
|
+ return { ...node, child: child };
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果节点map为true,或者所有子节点的map都为true,返回null
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (obj.code == 0) {
|
|
|
+ set_treeData(treeDataDefault);
|
|
|
+ } else {
|
|
|
+ const result = treeDataDefault.map(a => {
|
|
|
+ return filterNodes(a);
|
|
|
+ });
|
|
|
+
|
|
|
+ set_treeData(result.filter(b => b != null) as any);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ const onExpand = (newExpandedKeys: React.Key[]) => {
|
|
|
+ setExpandedKeys(newExpandedKeys);
|
|
|
+ setAutoExpandParent(false);
|
|
|
+ };
|
|
|
+
|
|
|
+ const generateList = (data: getTreeDataRespType[]) => {
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ const node = data[i];
|
|
|
+ const { code, name } = node;
|
|
|
+ dataList.push({ code: code, name: name });
|
|
|
+ if (node.child) {
|
|
|
+ generateList(node.child);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ generateList(treeData as any);
|
|
|
+
|
|
|
+
|
|
|
+ const getTreeReqFunc = async (computeDate: string, type: string) => {
|
|
|
+ const resp = await getTreeData(computeDate, type);
|
|
|
+ set_treeData(resp);
|
|
|
+ set_treeDataDefault(resp);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ const handleResize = (e: any) => {
|
|
|
+ const wH = e.target.innerHeight;
|
|
|
+ const tableHeight = wH - 290;
|
|
|
+ set_tableH(tableHeight);
|
|
|
+ }
|
|
|
+
|
|
|
+ function doResize() {
|
|
|
+ setTimeout(() => {
|
|
|
+ const ev: any = new Event('resize');
|
|
|
+ window.dispatchEvent(ev);
|
|
|
+ }, 0)
|
|
|
+ }
|
|
|
+
|
|
|
+ const computeHandle = () => {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '注意',
|
|
|
+ content: '重新计算会覆盖原有数据,确定要继续计算操作?'
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const saveHandle = async () => {
|
|
|
+
|
|
|
+ const resp = await save(needSaveData);
|
|
|
+ if (resp) {
|
|
|
+ message.success('操作成功!');
|
|
|
+ set_ifEditMode(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const getJiezhuanStatusHandle = async () => {
|
|
|
+ const resp = await getJiezhuanStatus(currentComputeDate as string);
|
|
|
+ if (resp == 2) {
|
|
|
+ set_ifBanAllAction(true);
|
|
|
+ } else {
|
|
|
+ set_ifBanAllAction(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+
|
|
|
+ if (currentComputeDate) {
|
|
|
+ getTreeReqFunc(currentComputeDate, ifCheckPage ? '1' : '0');
|
|
|
+ getCheckStatus(currentComputeDate);
|
|
|
+ getJiezhuanStatusHandle();
|
|
|
+
|
|
|
+ }
|
|
|
+ }, [currentComputeDate]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ //tableRef.current?.reload();
|
|
|
+
|
|
|
+ if (currentComputeDate && currentSelectedTreeNode) {
|
|
|
+
|
|
|
+ if (!ifCheckPage) {
|
|
|
+ getCurrentCommitStatus();
|
|
|
+ }
|
|
|
+ if (ifCheckPage) {
|
|
|
+ getCurrentUnitCheckStatus();
|
|
|
+ }
|
|
|
+
|
|
|
+ getTableData({});
|
|
|
+ }
|
|
|
+
|
|
|
+ }, [currentSelectedTreeNode, currentComputeDate]);
|
|
|
+
|
|
|
+ //console.log({inputsRef,inputsRefKeys});
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ //初始化左侧树结构数据后
|
|
|
+
|
|
|
+ if (treeData?.length > 0) {
|
|
|
+ if (!currentSelectedTreeNode) {
|
|
|
+ if (treeData[0].child && treeData[0].child.length > 0) {
|
|
|
+ const [node, nodeParent] = getDeepestTreeData(treeData[0], 'child');
|
|
|
+
|
|
|
+ set_currentSelectedTreeNode(node);
|
|
|
+ setExpandedKeys([nodeParent.code]);
|
|
|
+ getCurrentCommitStatus();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [treeData]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (location.pathname == "/secondaryDistribute/secondaryDitriCheck") {
|
|
|
+ set_ifCheckPage(true);
|
|
|
+ } else { set_ifCheckPage(false); }
|
|
|
+ }, [location])
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (needSaveData) {
|
|
|
+ buildTableData(needSaveData, inputsRefKeys);
|
|
|
+ }
|
|
|
+ }, [needSaveData]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (dataSource && Object.keys(inputsRef.current).length > 0) {
|
|
|
+ currentInputRefKeys && inputsRef.current[currentInputRefKeys].focus();
|
|
|
+ }
|
|
|
+ }, [dataSource])
|
|
|
+
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (auditType == '1') {
|
|
|
+ //当审核中时,禁掉所有操作
|
|
|
+ set_commitStatus('1');
|
|
|
+ }
|
|
|
+ }, [auditType]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+
|
|
|
+ let keys: string[] = [];
|
|
|
+
|
|
|
+ if (ifEditMode && needSaveData) {
|
|
|
+ //获取所有输入框的ref key
|
|
|
+ const { userList } = needSaveData;
|
|
|
+ userList.forEach((a: any) => {
|
|
|
+ a.itemValue.forEach((b: any) => {
|
|
|
+ keys.push(`${a.account}-${b.code}`)
|
|
|
+ })
|
|
|
+ });
|
|
|
+ set_inputsRefKeys(keys);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (needSaveData) {
|
|
|
+ if (ifEditMode) {
|
|
|
+ gennerateColumns(needSaveData, keys)
|
|
|
+ } else {
|
|
|
+ gennerateColumns(needSaveData)
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ifEditMode) {
|
|
|
+ set_currentInputRefKeys(undefined);
|
|
|
+ getTableData({}); //重新拉数据
|
|
|
+ }
|
|
|
+
|
|
|
+ }, [ifEditMode]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (ifEditMode && Object.keys(inputsRef.current).length > 0 && inputsRefKeys.length > 0) {
|
|
|
+
|
|
|
+ inputsRef.current[`${inputsRefKeys[0]}`].focus();
|
|
|
+ set_currentInputRefKeys(inputsRefKeys[0]);
|
|
|
+ }
|
|
|
+ }, [inputsRef, inputsRefKeys])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ set_tableColumn(column as ProColumns[]);
|
|
|
+ getCurrentComputeDate();
|
|
|
+ window.addEventListener('resize', (e) => handleResize(e)) //监听窗口大小改变
|
|
|
+ doResize();
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ window.removeEventListener('resize', (e) => handleResize(e))
|
|
|
+ }
|
|
|
+ }, []);
|
|
|
+
|
|
|
+
|
|
|
+ return (
|
|
|
+
|
|
|
+ <div className='UnitCheckProjectScore'>
|
|
|
+ {
|
|
|
+ treeFilterVisible && (
|
|
|
+ <div className='selecterList'>
|
|
|
+ <div onClick={() => changeTreeDataFilter({ name: '全部单元', code: 0 })} className={currentTreeDataFilter.code == 0 ? 'list on' : 'list'}>全部单元</div>
|
|
|
+ <div onClick={() => changeTreeDataFilter({ name: ifCheckPage ? '未审核' : '未提交', code: 1 })} className={currentTreeDataFilter.code == 1 ? 'list on' : 'list'}>{ifCheckPage ? '未审核' : '未提交'}</div>
|
|
|
+ <div onClick={() => changeTreeDataFilter({ name: ifCheckPage ? '已审核' : '已提交', code: 2 })} className={currentTreeDataFilter.code == 2 ? 'list on' : 'list'}>{ifCheckPage ? '已审核' : '已提交'}</div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ <div className='leftTree'>
|
|
|
+ <div className='search'>
|
|
|
+ <Input
|
|
|
+ className='searchInput'
|
|
|
+ placeholder="请输入类目名称"
|
|
|
+ size='small'
|
|
|
+ allowClear
|
|
|
+ style={{ width: 158 }}
|
|
|
+ onChange={onTreeSearchKeyChange}
|
|
|
+ suffix={
|
|
|
+ <SearchIcon type='iconsousuo' />
|
|
|
+ }
|
|
|
+ />
|
|
|
+ <Tooltip placement="top" title={currentTreeDataFilter.name}>
|
|
|
+ <div className={currentTreeDataFilter.code == 0 ? 'filter' : currentTreeDataFilter.code == 1 ? 'filter orange' : 'filter blue'} onClick={() => set_treeFilterVisible(true)}></div>
|
|
|
+ </Tooltip>
|
|
|
+ </div>
|
|
|
+ {
|
|
|
+ treeData && treeData.length > 0 && currentSelectedTreeNode && (
|
|
|
+ <DirectoryTree
|
|
|
+ fieldNames={{ title: 'name', key: 'code', children: 'child' }}
|
|
|
+ rootStyle={{ height: '100%', paddingBottom: 50, overflowY: 'scroll', overflowX: 'hidden' }}
|
|
|
+ onSelect={onSelect}
|
|
|
+ onExpand={onExpand}
|
|
|
+ expandedKeys={expandedKeys}
|
|
|
+ autoExpandParent={autoExpandParent}
|
|
|
+ selectedKeys={[currentSelectedTreeNode.code]}
|
|
|
+ blockNode={true}
|
|
|
+
|
|
|
+ icon={() => null}
|
|
|
+
|
|
|
+ titleRender={
|
|
|
+ (nodeData: any) => {
|
|
|
+ const strTitle = nodeData.name as string;
|
|
|
+ const index = strTitle.indexOf(searchValue);
|
|
|
+ const beforeStr = strTitle.substring(0, index);
|
|
|
+ const afterStr = strTitle.slice(index + searchValue.length);
|
|
|
+ const title =
|
|
|
+ index > -1 ? (
|
|
|
+ <span>
|
|
|
+ {beforeStr}
|
|
|
+ <span className="site-tree-search-value" style={{ color: '#3377ff', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{searchValue}</span>
|
|
|
+ {afterStr}
|
|
|
+ </span>
|
|
|
+ ) : (
|
|
|
+ <span className='strTitle'>{strTitle}</span>
|
|
|
+ );
|
|
|
+ return <div style={{
|
|
|
+ display: 'flex', flexDirection: 'row',
|
|
|
+ width: '100%',
|
|
|
+ justifyContent: 'space-between', alignItems: 'center', height: 32,
|
|
|
+ borderRadius: '4px',
|
|
|
+ overflow: 'hidden',
|
|
|
+ color: '#17181A',
|
|
|
+ textOverflow: 'ellipsis',
|
|
|
+ whiteSpace: 'nowrap'
|
|
|
+
|
|
|
+ }}>
|
|
|
+ {title}
|
|
|
+ {!nodeData.map && <span className={nodeData.unitType ? 'point lastChild' : 'point'}></span>}
|
|
|
+ </div>
|
|
|
+ }
|
|
|
+ }
|
|
|
+ defaultSelectedKeys={[treeData[0].child[0].code]}
|
|
|
+ treeData={treeData as unknown as DataNode[]}
|
|
|
+ // treeData={treeDataNew}
|
|
|
+ switcherIcon={(props: any) => {
|
|
|
+ const { expanded } = props;
|
|
|
+ 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} />
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }
|
|
|
+ </div>
|
|
|
+ {/* <div style={{width:16,height:'92vh',background:'#F5F7FA'}}></div> */}
|
|
|
+ <div className='rightContent'>
|
|
|
+ <BMSPagecontainer title={`核算年月:${currentComputeDate}`} ghost>
|
|
|
+ <div className='tabContent'>
|
|
|
+ <div className='tableToolbar'>
|
|
|
+ <div className='search'>
|
|
|
+ <span className='label'>检索:</span>
|
|
|
+ <Input placeholder={'请输入项目名称'} allowClear
|
|
|
+ suffix={
|
|
|
+ <IconFont style={{ color: '#99A6BF' }} type="iconsousuo" />
|
|
|
+ }
|
|
|
+ onChange={(e) => {
|
|
|
+
|
|
|
+ }}
|
|
|
+
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className='btnGroupWrap'>
|
|
|
+ {
|
|
|
+ (!ifCheckPage && !ifBanAllAction) && (
|
|
|
+ //计算界面
|
|
|
+ <>
|
|
|
+ <Popover open={ifShowTip} content={auditType == '1' ? '当前处于审核中,无法操作!' : '当前处于提交中,无法操作!'} >
|
|
|
+ <div className={commitStatus != '0' || auditType == '1' ? 'btnGroup disabled' : 'btnGroup'}
|
|
|
+ /**
|
|
|
+ * 当审核中,三个操作按钮都不可点击
|
|
|
+ * 当非审核中,生成和添加不可操作
|
|
|
+ */
|
|
|
+ onMouseEnter={() => auditType == '0' ? commitStatus == '1' ? set_ifShowTip(true) : set_ifShowTip(false) : set_ifShowTip(true)}
|
|
|
+ onMouseLeave={() => set_ifShowTip(false)}
|
|
|
+ >
|
|
|
+ {!ifEditMode && <span className='compute cancel' onClick={commitStatus == '0' && auditType != '1' ? () => computeHandle() : () => { }}>获取</span>}
|
|
|
+ {importData()}
|
|
|
+ {!ifEditMode && <span className='cancel' onClick={commitStatus == '0' && auditType != '1' ? () => set_ifEditMode(true) : () => { }}>编辑</span>}
|
|
|
+ {ifEditMode && <span className='cancel' onClick={commitStatus == '0' ? () => set_ifEditMode(false) : () => { }}>取消</span>}
|
|
|
+ {ifEditMode && <span className='editBtn' onClick={commitStatus == '0' && auditType != '1' ? () => saveHandle() : () => { }}>保存</span>}
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </Popover>
|
|
|
+ {!ifEditMode && <div key="" className={auditType == '1' ? 'commit disabled' : 'commit'} onClick={() => auditType == '0' ? commitBtnhandle() : () => { }}>{commitStatus == '1' ? '取消提交' : '提交'}</div>}
|
|
|
+ </>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ {
|
|
|
+ !ifBanAllAction && ifCheckPage && userFunctionInThispage && (userFunctionInThispage.findIndex((a: { code: string, name: string }) => a.code == 'audit') != -1) && (
|
|
|
+ <>
|
|
|
+ <div className={'commit gray'} onClick={() => commitBtnhandle(1)}>{currentUnitAuditType == '1' ? '取消审核单个' : '审核单个'}</div>
|
|
|
+ <div className={'commit'} onClick={() => commitBtnhandle(2)}>{auditType == '1' ? '取消审核全部' : '审核全部'}</div>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ {currentSelectedTreeNode && <BMSTable pagination={false} actionRef={tableRef} rowKey='id'
|
|
|
+ scroll={{ x: 120 * tableColumn.length, y: tableH }}
|
|
|
+ columns={[...tableColumn]} dataSource={dataSource}
|
|
|
+ />}
|
|
|
+ </div>
|
|
|
+ </BMSPagecontainer>
|
|
|
+ </div >
|
|
|
+ </div >
|
|
|
+
|
|
|
+ );
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+export default UnitCheckProjectScore;
|