ylj20011123 e876df2bde update
2025-09-30 14:42:08 +08:00

1242 lines
52 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useRef, useState, Suspense } from 'react';
import moment from 'moment'; // 时间相关引用,没有使用可以删除
import numeral from "numeral"; // 数字相关引用,没有使用可以删除
import { connect } from 'umi';
import ReactHTMLTableToExcel from "react-html-table-to-excel";
import useRequest from '@ahooksjs/use-request'; // 请求数据的引用
import Draggable from 'react-draggable';
import SubMenu from "antd/lib/menu/SubMenu";
import ProTable from '@ant-design/pro-table';
import ProDescriptions from '@ant-design/pro-descriptions';
import ProForm, { ProFormDatePicker, ProFormDateTimePicker, ProFormMoney, ProFormSelect, ProFormText, ProFormTextArea, ProFormUploadButton } from '@ant-design/pro-form';
import { MenuFoldOutlined, PlusOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-layout';
import { Button, Col, Drawer, message, Row, Popconfirm, Space, Image, Modal, Form, Switch, Upload, Tooltip, Descriptions, TreeSelect, Spin, Typography } from 'antd';
import type { CurrentUser } from "umi";
import type { ConnectState } from '@/models/connect';
import type { ActionType, ProColumns } from '@ant-design/pro-table';
import type { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import type { FormInstance } from 'antd';
import type { INVESTMENTANALYSISModel } from './data';
import { getFieldEnumTree, getFieldEnumName, getServerpartTree } from "@/services/options"; // 枚举的引用,没有使用可以删除
import { getList, delinvestmentanalysis, updateinvestmentanalysis, handleGetInvestmentReport, handleGetNestingIAReport } from './service'; // 接口相关对象的引用
import PageTitleBox from '@/components/PageTitleBox';
import InvestmentPromotionDetail from './components/index.tsx'
import session from '@/utils/session';
import { handleGetListObj } from '@/utils/utils';
import LeftSelectTree from '../../settlementAccount/component/leftSelectTree';
import BusinessanalysisDetail from "@/pages/reports/Finance/businessAnalysis/components/businessanalysisDetail";
import { formatTreeData } from '@/utils/format';
const handelDelete = async (investmentanalysisid: number) => {
const hide = message.loading('正在删除...');
try {
const result = await delinvestmentanalysis(investmentanalysisid);
hide();
if (result.Result_Code !== 100) {
message.error(`${result.Result_Desc}` || `${result.Result_Code}:删除失败`);
return false;
}
message.success('删除成功!');
return true;
} catch (error) {
hide();
message.error('删除失败');
return false;
}
};
const handleAddUpdate = async (fields: INVESTMENTANALYSISModel) => {
const hide = message.loading('正在提交...');
const result = await updateinvestmentanalysis(fields);
hide();
if (result.Result_Code !== 100) {
message.error(`${result.Result_Desc}` || `${result.Result_Code}:提交失败`);
return false;
}
return result.Result_Data ? result.Result_Data : true;
};
const INVESTMENTANALYSISTable: React.FC<{ currentUser: CurrentUser | undefined }> = (props) => {
const { currentUser } = props
const downloadBtnRef = useRef<any>()
const actionRef = useRef<ActionType>();
const actionTableRef = useRef<ActionType>();
const BusinessDetailRef = useRef<any>();
const formRef = useRef<FormInstance>();
const [currentRow, setCurrentRow] = useState<INVESTMENTANALYSISModel>();
const [showDetail, setShowDetail] = useState<boolean>();
const [modalVisible, handleModalVisible] = useState<boolean>();
const [confirmLoading, handleConfirmLoading] = useState<boolean>(false) // 弹出框的内容表单是否在提交
const [searchParams, setSearchParams] = useState<any>();
const [SERVERPARTTYPEObj, setSERVERPARTTYPEObj] = useState<any>()
// 是否点击了搜索按钮
const clickTableBtnRef = useRef<boolean>(false)
// 弹出框拖动效果
const [bounds, setBounds] = useState<{ left: number, right: number, top: number, bottom: number }>() // 移动的位置
const [disabled, setDraggleDisabled] = useState<boolean>() // 是否拖动
const draggleRef = React.createRef<any>()
const [collapsible, setCollapsible] = useState<boolean>(false)
// 树相关的属性和方法
const [selectedId, setSelectedId] = useState<string>()
// 显示详情抽屉
const [showNewDetail, setShowNewDetail] = useState<boolean>(false)
// 显示行详情
const [currentNewRow, setCurrentNewRow] = useState<any>()
// 全部的服务区string
const [allServerpartStr, setAllServerpartStr] = useState<string>()
// 选中的经营业态
const [BusinessTradeType, setBusinessTradeType] = useState<any>()
const [reqDetailList, setReqDetailList] = useState<any>(); // 合计项数据源
// 是否显示打印的表格
const [showExportTable, setShowExportTable] = useState<boolean>(false)
// 数据更新时间
const [updateTime, setUpdateTime] = useState<any>()
// 表格的加载效果
const [tableLoading, setTableLoading] = useState<boolean>(false)
const BusinessTradeIdsObj = session.get('BusinessTradeIdsObj')
const ServerpartTypeObj = session.get('ServerpartTypeObj')
// 表格数据
const [tableData, setTableData] = useState<any>()
const [BusinessTradeObj, setBusinessTradeObj] = useState<any>()
// 导出的加载效果
const [showLoading, setShowLoading] = useState<boolean>(false)
const { loading: BusinessTradeIdsLoading, data: BusinessTradeIdsList } = useRequest(async () => {
const data = await getFieldEnumTree({ FieldExplainField: 'BusinessTradeIds', sessionName: 'BusinessTradeIds' });
const userEnum: any = handleGetListObj(data)
setBusinessTradeObj(userEnum)
return data
})
const [columnsStateMap, setColumnsStateMap] = useState<any>({
// ADJUST_RENTRANGE: { show: false },
SERVERPART_TYPE: { show: false },
projectDetail: { show: false },
subLevelBusiness: { show: false },
firstLevelBusiness: { show: false },
PROFIT: { show: false },
});
// 加载服务区树
const { loading: treeLoading, data: treeViews } = useRequest(async () => {
const data = await getServerpartTree(currentUser?.ProvinceCode, currentUser?.CityAuthority, true, true, true, null, 1000)
if (data && data.length > 0) {
const list: any = []
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
item.children.forEach((subItem: any) => {
list.push(subItem)
})
}
})
const selectedIds = list.filter(n => n?.type === 1)
let str: string = ''
if (selectedIds && selectedIds.length > 0) {
selectedIds.forEach((item: any) => {
if (str) {
str += `,${item.value}`
} else {
str = item.value
}
})
setAllServerpartStr(str)
}
}
return data
})
const onDraggaleStart = (event, uiData) => {
const { clientWidth, clientHeight } = window.document.documentElement;
const targetRect = draggleRef.current?.getBoundingClientRect();
if (!targetRect) {
return;
}
setBounds({
left: -targetRect.left + uiData.x,
right: clientWidth - (targetRect.right - uiData.x),
top: -targetRect.top + uiData.y,
bottom: clientHeight - (targetRect.bottom - uiData.y),
});
};
// 拖动结束
const exportTable = (e) => {
e.stopPropagation(); // 防止Collapse组件收起
const main = document.getElementsByClassName('saleReportHideBox')[0]
const thead = main.querySelector('thead').cloneNode(true); // 深克隆DOM节点
const tbody = main.querySelector('tbody').cloneNode(true); // 深克隆DOM节点
const container = document.querySelector('#hiddenBox');
const tempTable = document.createElement('table');
tempTable.appendChild(thead);
tempTable.appendChild(tbody);
tempTable.setAttribute('id', 'table-to-xls-BUSINESSANALYSIS'); // 给table添加id值与按钮上的table字段对应
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
setShowLoading(false)
downloadBtnRef.current.handleDownload();
setShowExportTable(false)
tempTable.remove() // 防止重复打印一个内容
}
// 定义列表字段内容
const columns: any = [
{
title: '项目结束',
dataIndex: 'DueStartDate|DueEndDate',
aiDataIndex: "DueStartDate|DueEndDate",
hideInTable: true,
order: 1,
valueType: "dateRange",
hideInDescriptions: true,
initialValue: [moment().startOf("month"), moment().add(5, 'months').endOf("month")],
search: {
transform: (value) => {
return {
DueStartDate: moment(value[0]).startOf("month").format('YYYY-MM-DD'),
DueEndDate: moment(value[1]).endOf("month").format('YYYY-MM-DD')
};
},
},
fieldProps: {
picker: "month",
// format: 'YYYY-MM-DD',
format: 'YYYY-MM',
onChange: (e: any) => {
if (e && e.length > 0 && e[0] && e[1]) {
formRef.current?.setFieldsValue({
staticDate: [moment(e[0]._d).startOf("month").format('YYYY-MM-DD'), moment(e[1]._d).endOf("month").format('YYYY-MM-DD')]
})
}
}
// disabledDate: (current: any) => current && current > moment()
}
},
{
dataIndex: 'BUSINESS_TRADE',
aiDataIndex: "BUSINESS_TRADE",
title: '经营业态',
width: 150,
colSize: 2,
hideInTable: true,
valueType: 'treeSelect',
align: 'center',
fieldProps: {
multiple: true,
treeDefaultExpandAll: true,
allowClear: true,
fieldNames: {
title: "label",
key: "value"
},
treeData: BusinessTradeIdsList,
},
userEnum: BusinessTradeObj
},
{
dataIndex: 'SERVERPART_TYPE',
aiDataIndex: "SERVERPART_TYPE",
title: '服务区类型',
width: 120,
valueType: 'treeSelect',
hideInTable: true,
align: 'center',
sorter: {
compare: (a, b) => a.SERVERPART_TYPE - b.SERVERPART_TYPE,
multiple: 3,
},
defaultSortOrder: 'ascend',
request: async () => {
const data = await getFieldEnumTree({ FieldExplainField: 'SERVERPART_TYPE', sessionName: 'SERVERPART_TYPE' });
const userEnum: any = handleGetListObj(data)
setSERVERPARTTYPEObj(userEnum)
return data
},
userEnum: SERVERPARTTYPEObj,
fieldProps: {
allowClear: true,
multiple: true,
},
render: (_, record) => {
return <span>{getFieldEnumName('SERVERPART_TYPE', record?.SERVERPART_TYPE)}</span>
},
},
{
dataIndex: 'ContainHoliday',
aiDataIndex: "ContainHoliday",
title: '数据口径',
valueType: 'select',
valueEnum: {
0: '正常的值(带节假日的)',
1: '节假日',
2: '不含节假日',
},
userEnum: {
0: '正常的值(带节假日的)',
1: '节假日',
2: '不含节假日',
},
initialValue: '0',
hideInTable: true,
hideInDescriptions: true,
},
{
dataIndex: 'SERVERPARTSHOP_NAME|SERVERPART_NAME|SERVERPART_NAME',
title: '服务区名称',
align: 'center',
hideInSearch: true,
width: 150,
ellipsis: true,
fixed: 'left',
render: (_, record) => {
return record?.SERVERPARTSHOP_NAME || record?.SERVERPART_NAME || record?.SPREGIONTYPE_NAME
}
},
{
dataIndex: 'SERVERPART_TYPE',
title: '服务区类型',
align: 'center',
valueEnum: ServerpartTypeObj,
valueType: 'select',
width: 150,
ellipsis: true,
hideInSearch: true,
},
{
dataIndex: 'SERVERPARTSHOP_NAME',
title: '门店名称',
align: 'center',
width: 150,
ellipsis: true,
hideInSearch: true,
fixed: 'left',
render: (_, record) => {
return <a onClick={() => {
if (!record?.BUSINESSPROJECT_ID) {
message.success('暂无项目!')
return
}
setCurrentNewRow({
...record,
BusinessTradeType
})
console.log('dsajkdjaskd', {
...record,
BusinessTradeType
});
setShowNewDetail(true)
}}>
{record?.SERVERPARTSHOP_NAME || ""}
</a>
}
},
{
title: "项目情况信息",
dataIndex: "projectDetail",
hideInSearch: true,
children: [
{
dataIndex: 'BUSINESSPROJECT_NAME',
title: '经营项目名称',
align: 'center',
hideInSearch: true,
width: 200,
ellipsis: true,
},
{
dataIndex: 'PROJECT_STARTDATE',
title: '项目开始日期',
align: 'center',
hideInSearch: true,
width: 150,
ellipsis: true,
},
{
dataIndex: 'PROJECT_ENDDATE',
title: '项目结束日期',
align: 'center',
hideInSearch: true,
width: 150,
ellipsis: true,
},
]
},
{
dataIndex: 'RENT_RATIO',
title: <div style={{ textAlign: 'center' }}>(%)</div>,
width: 100,
align: 'center',
hideInSearch: true,
render: (_, record) => {
let str: string = `已付租金${record?.ROYALTY_PRICE}万元`
return <Tooltip title={record?.level === 4 ? str : ""}>
{record?.RENT_RATIO}
</Tooltip>
}
},
// {
// dataIndex: 'ROYALTY_PRICE',
// title: <div style={{ textAlign: 'center' }}>已付租金</div>,
// width: 160,
// align: 'right',
// hideInSearch: true,
// },
{
dataIndex: 'PERIOD_DEGREE',
title: '项目进度(%) ',
align: 'center',
hideInSearch: true,
width: 100,
ellipsis: true,
},
{
dataIndex: "RENTCHANGE",
title: "保底租金变化(万元)",
hideInSearch: true,
children: [
{
dataIndex: 'ADJUST_RENT',
title: <div style={{ textAlign: 'center' }}></div>,
width: 140,
align: 'right',
hideInSearch: true,
render: (_, record) => {
// ADJUST_RENTRANGE
let str: string = `${record?.ADJUST_RENTRANGE || ""}`
return <Tooltip title={str}>
{record?.ADJUST_RENT ? record?.ADJUST_RENT.toLocaleString() : ""}
</Tooltip>
}
},
{
dataIndex: 'MINTURNOVER',
title: <div style={{ textAlign: 'center' }}></div>,
align: 'right',
hideInSearch: true,
width: 160,
valueType: "digit",
sorter: {
compare: (a, b) => (a.MINTURNOVER) - (b.MINTURNOVER)
},
ellipsis: true,
},
// {
// dataIndex: 'ADJUST_RENTRANGE',
// title: <div style={{ textAlign: 'center' }}>调整租金范围</div>,
// width: 160,
// align: 'right',
// hideInSearch: true,
// },
{
dataIndex: 'ADJUST_AMOUNT',
title: <div style={{ textAlign: 'center' }}></div>,
width: 140,
align: 'right',
valueType: "digit",
sorter: {
compare: (a, b) => (a.ADJUST_AMOUNT) - (b.ADJUST_AMOUNT)
},
hideInSearch: true,
},
]
},
{
dataIndex: "ratio",
title: "提成建议变化(%)",
hideInSearch: true,
children: [
{
dataIndex: 'ADJUST_RATIO',
// title: '调整后提成比例',
title: '提成建议',
width: 120,
align: 'center',
hideInSearch: true,
render: (_, record) => {
let str: string = record?.COMMISSION_AVGRATIO ? record?.COMMISSION_AVGRATIO > record?.ADJUST_RATIO ? `${record?.ADJUST_RATIO}-${record?.COMMISSION_AVGRATIO}` : `${record?.COMMISSION_AVGRATIO}-${record?.ADJUST_RATIO}` : record?.ADJUST_RATIO
return <Tooltip title={record?.level === 4 ? str : ''
}>
{record?.ADJUST_RATIO}
</Tooltip >
}
},
{
dataIndex: 'GUARANTEERATIO',
// title: '当期提成比例',
title: '原提成',
align: 'center',
hideInSearch: true,
width: 120,
ellipsis: true,
},
{
dataIndex: 'RATIOCHANGE',
// title: '当期提成比例',
title: '提成变化',
align: 'center',
hideInSearch: true,
width: 120,
sorter: {
compare: (a, b) => (a.ADJUST_RATIO - a.GUARANTEERATIO) - (b.ADJUST_RATIO - b.GUARANTEERATIO)
},
ellipsis: true,
render: (_, record) => {
let res: number = subtractAndFormat(record?.ADJUST_RATIO - record?.GUARANTEERATIO)
return record.level === 4 ? res : ""
}
},
]
},
{
dataIndex: "subLevelBusiness",
title: "经营业态盈利分析",
hideInSearch: true,
children: [
{
dataIndex: 'BUSINESS_TRADE',
title: '经营业态',
width: 120,
align: 'center',
valueType: 'select',
valueEnum: BusinessTradeIdsObj,
hideInSearch: true,
},
{
dataIndex: 'COMMISSION_RATIO',
// title: '建议提成比例',
title: '提成比例',
align: 'center',
hideInSearch: true,
width: 120,
ellipsis: true,
},
{
dataIndex: 'TRADE_PROJECTCOUNT',
title: '同业项目(个)',
align: 'center',
hideInSearch: true,
width: 120,
ellipsis: true,
},
{
dataIndex: 'PROFIT_AVG',
title: <div style={{ textAlign: 'center' }}>(%)</div>,
align: 'right',
hideInSearch: true,
valueType: "digit",
width: 120,
ellipsis: true,
},
]
},
{
dataIndex: "firstLevelBusiness",
title: "父级业态盈利分析",
hideInSearch: true,
children: [
{
dataIndex: 'BUSINESS_PTRADE',
title: '父级业态',
width: 120,
align: 'center',
valueType: 'select',
valueEnum: BusinessTradeIdsObj,
hideInSearch: true,
},
{
dataIndex: 'TRADE_SHOPCOUNT',
// title: '同业态门店(个)',
title: '同业态项目(个)',
align: 'center',
hideInSearch: true,
width: 140,
ellipsis: true,
},
{
dataIndex: 'COMMISSION_MINRATIO',
title: '最低提成(%)',
align: 'center',
hideInSearch: true,
width: 140,
ellipsis: true,
},
{
dataIndex: 'COMMISSION_MAXRATIO',
title: '最高提成(%)',
align: 'center',
hideInSearch: true,
width: 140,
ellipsis: true,
},
{
dataIndex: 'GUARANTEE_MINPRICE',
title: <div style={{ textAlign: 'center' }}></div>,
align: 'right',
hideInSearch: true,
width: 170,
ellipsis: true,
},
{
dataIndex: 'GUARANTEE_MAXPRICE',
title: <div style={{ textAlign: 'center' }}></div>,
align: 'right',
hideInSearch: true,
width: 170,
ellipsis: true,
},
{
dataIndex: 'COMMISSION_AVGRATIO',
title: '平均提成比例(%)',
align: 'center',
hideInSearch: true,
width: 140,
ellipsis: true,
},
{
dataIndex: 'GUARANTEE_AVGPRICE',
title: <div style={{ textAlign: 'center' }}></div>,
align: 'right',
hideInSearch: true,
width: 170,
ellipsis: true,
},
]
},
{
dataIndex: "PROFIT",
title: "商家盈利分析(万元)",
hideInSearch: true,
children: [
{
dataIndex: 'PROFIT_AMOUNT',
title: <div style={{ textAlign: 'center' }}></div>,
valueType: 'digit',
align: 'right',
hideInSearch: true,
width: 140,
ellipsis: true,
render: (_, record) => {
return Number(formatDecimal(record?.PROFIT_AMOUNT || 0)).toLocaleString()
}
},
{
dataIndex: 'REVENUE_LASTAMOUNT',
title: <div style={{ textAlign: 'center' }}></div>,
valueType: 'digit',
align: 'right',
hideInSearch: true,
width: 140,
ellipsis: true,
render: (_, record) => {
return Number(formatDecimal(record?.REVENUE_LASTAMOUNT || 0)).toLocaleString()
}
},
// {
// dataIndex: 'REVENUE_AVGAMOUNT',
// title: <div style={{ textAlign: 'center' }}>本期平均营收</div>,
// align: 'right',
// valueType: 'digit',
// hideInSearch: true,
// width: 140,
// ellipsis: true,
// render: (_, record) => {
// return formatDecimal(record?.REVENUE_AVGAMOUNT / 10000 || 0)
// }
// },
// {
// dataIndex: 'REVENUE_AVGAMOUNTCHANGE',
// title: <div style={{ textAlign: 'center' }}>营收变化</div>,
// align: 'right',
// valueType: 'digit',
// hideInSearch: true,
// width: 140,
// ellipsis: true,
// render: (_, record) => {
// return formatDecimal((record?.REVENUE_AVGAMOUNT - record?.REVENUE_LASTAMOUNT) / 10000)
// }
// },
{
dataIndex: 'PROFIT_TOTALAMOUNT',
title: <div style={{ textAlign: 'center' }}></div>,
valueType: 'digit',
align: 'right',
hideInSearch: true,
width: 140,
ellipsis: true,
render: (_, record) => {
let str: string = `${record?.PROFIT_INFO}`
return <Tooltip title={str}>
{Number(formatDecimal(record?.PROFIT_TOTALAMOUNT || 0)).toLocaleString()}
</Tooltip>
}
},
]
},
// {
// dataIndex: 'PROFIT_INFO',
// title: '盈利金额信息',
// valueType: 'money',
// align: 'center',
// hideInSearch: true,
// width: 150,
// ellipsis: true,
// },
// {
// dataIndex: 'INVESTMENTANALYSIS_STATE',
// title: '有效状态',
// align: 'center',
// hideInSearch: true,
// width: 150,
// ellipsis: true,
// },
// {
// dataIndex: 'STAFF_NAME',
// title: '操作人员',
// align: 'center',
// hideInSearch: true,
// },
// {
// dataIndex: 'RECORD_DATE',
// title: '记录时间',
// valueType: 'date',
// align: 'center',
// hideInSearch: true,
// },
// {
// dataIndex: 'INVESTMENTANALYSIS_DESC',
// title: '备注说明',
// align: 'center',
// hideInSearch: true,
// },
// {
// dataIndex: 'option',
// title: '操作',
// valueType: 'option',
// fixed: 'right',
// align: 'center',
// width: 120,
// hideInSearch: true,
// render: (_, record) => {
// return (
// <Space>
// <a
// onClick={() => {
// setCurrentRow(record);
// setShowDetail(true);
// }}
// >
// 详情
// </a>
// </Space>
// );
// },
// },
];
// 处理数字 截取
const formatDecimal = (num: number) => {
// 转换为字符串处理
const numStr = String(num);
// 检查是否是整数
if (!numStr.includes('.')) {
return numStr; // 直接返回整数部分
}
// 分割整数和小数部分
const [integerPart, decimalPart] = numStr.split('.');
// 处理小数部分
let formattedDecimal = decimalPart;
if (decimalPart.length > 2) {
formattedDecimal = decimalPart.substring(0, 2); // 截取前两位
} else if (decimalPart.length === 1) {
formattedDecimal = decimalPart; // 保留一位
}
// 拼接结果(注意:小数部分全零时仍会显示,如 1.00 → 1.0
return `${integerPart}.${formattedDecimal}`;
}
const subtractAndFormat = (result: number) => {
// 处理结果的小数部分
const decimalPart = result.toString().split('.')[1];
// 判断小数位数
if (decimalPart) {
if (decimalPart.length > 2) {
// 大于两位小数,截取两位(不四舍五入)
return parseFloat(result.toFixed(2).toString());
} else {
// 小于等于两位小数,直接返回
return result;
}
} else {
// 没有小数,返回整数
return result;
}
}
const handleGetTableData = async (params: any) => {
const searchWholeParams = {
ProvinceCode: currentUser?.ProvinceCode || '340000',
ServerpartId: selectedId,
ServerpartType: params?.SERVERPART_TYPE ? params?.SERVERPART_TYPE.toString() : "",
BusinessTrade: params?.BUSINESS_TRADE ? params?.BUSINESS_TRADE.toString() : "",
DueStartDate: params?.DueStartDate ? params?.DueStartDate : "",
DueEndDate: params?.DueEndDate ? params?.DueEndDate : "",
ContainHoliday: params?.ContainHoliday || ""
}
setTableLoading(true)
setSearchParams(searchWholeParams)
// const data = await handleGetInvestmentReport(searchWholeParams);
const data = await handleGetNestingIAReport(searchWholeParams);
if (data && data.length > 0) {
// item 合计层 subItem 片区层 thirdItem 服务区层 fourthItem 门店项目层
data.forEach((item: any) => {
if (item.children && item.children.length > 0) {
// 原提成合计
let FIRSTGUARANTEERATIOSUM: number = 0
// 原提成有值的个数
let FIRSTGUARANTEERATIOTOTAL: number = 0
// 提成建议
let FIRSTCOMMISSION_AVGRATIOSUM: number = 0
let FIRSTADJUST_RATIOSUM: number = 0
let FIRSTADJUST_RATIOTOTAL: number = 0
// 建议租金
let FIRSTADJUST_RENTSUM: number = 0
let FIRSTADJUST_RENTTOTAL: number = 0
// 当期租金
let FIRSTMINTURNOVERSUM: number = 0
let FIRSTMINTURNOVERTOTAL: number = 0
item.children.forEach((subItem: any) => {
if (subItem.children && subItem.children.length > 0) {
// 原提成合计
let SUBGUARANTEERATIOSUM: number = 0
// 原提成有值的个数
let SUBGUARANTEERATIOTOTAL: number = 0
// 提成建议
let SUBCOMMISSION_AVGRATIOSUM: number = 0
let SUBADJUST_RATIOSUM: number = 0
let SUBADJUST_RATIOTOTAL: number = 0
// 建议租金
let SUBADJUST_RENTSUM: number = 0
let SUBADJUST_RENTTOTAL: number = 0
// 当期租金
let SUBMINTURNOVERSUM: number = 0
let SUBMINTURNOVERTOTAL: number = 0
subItem.children.forEach((thirdItem: any) => {
if (thirdItem.children && thirdItem.children.length > 0) {
// 原提成合计
let GUARANTEERATIOSUM: number = 0
// 原提成有值的个数
let GUARANTEERATIOTOTAL: number = 0
// 提成建议
let COMMISSION_AVGRATIOSUM: number = 0
let ADJUST_RATIOSUM: number = 0
let ADJUST_RATIOTOTAL: number = 0
// 建议租金
let ADJUST_RENTSUM: number = 0
let ADJUST_RENTTOTAL: number = 0
// 当期租金
let MINTURNOVERSUM: number = 0
let MINTURNOVERTOTAL: number = 0
// 租金进度
let RENT_RATIOSUM: number = 0
let RENT_RATIOTOTAl: number = 0
// 项目进度
let PERIOD_DEGREESUM: number = 0
let PERIOD_DEGREETOTAL: number = 0
thirdItem.children.forEach((fourthItem: any, fourthIndex: number) => {
fourthItem.level = 4
fourthItem.index = fourthIndex + 1
if (fourthItem.GUARANTEERATIO) {
GUARANTEERATIOSUM += fourthItem.GUARANTEERATIO
GUARANTEERATIOTOTAL += 1
}
if (fourthItem.COMMISSION_AVGRATIO && fourthItem.ADJUST_RATIO) {
COMMISSION_AVGRATIOSUM += fourthItem.COMMISSION_AVGRATIO
ADJUST_RATIOSUM += fourthItem.ADJUST_RATIO
ADJUST_RATIOTOTAL += 1
}
if (fourthItem.ADJUST_RENT) {
ADJUST_RENTSUM += fourthItem.ADJUST_RENT
ADJUST_RENTTOTAL += 1
}
if (fourthItem.MINTURNOVER) {
MINTURNOVERSUM += fourthItem.MINTURNOVER
MINTURNOVERTOTAL += 1
}
if (fourthItem.RENT_RATIO > 0) {
RENT_RATIOSUM += fourthItem.RENT_RATIO
RENT_RATIOTOTAl += 1
}
if (fourthItem.PERIOD_DEGREE > 0) {
PERIOD_DEGREESUM += fourthItem.PERIOD_DEGREE
PERIOD_DEGREETOTAL += 1
}
})
thirdItem.GUARANTEERATIO = subtractAndFormat(GUARANTEERATIOSUM / GUARANTEERATIOTOTAL) || null
thirdItem.COMMISSION_AVGRATIO = subtractAndFormat(COMMISSION_AVGRATIOSUM / ADJUST_RATIOTOTAL) || null
thirdItem.ADJUST_RATIO = subtractAndFormat(ADJUST_RATIOSUM / ADJUST_RATIOTOTAL) || null
thirdItem.ADJUST_RENT = subtractAndFormat(ADJUST_RENTSUM)// / ADJUST_RENTTOTAL
thirdItem.MINTURNOVER = subtractAndFormat(MINTURNOVERSUM)// / MINTURNOVERTOTAL
thirdItem.RENT_RATIO = subtractAndFormat(RENT_RATIOSUM / RENT_RATIOTOTAl) || null
thirdItem.PERIOD_DEGREE = subtractAndFormat(PERIOD_DEGREESUM / PERIOD_DEGREETOTAL) || null
}
if (thirdItem.GUARANTEERATIO) {
SUBGUARANTEERATIOSUM += thirdItem.GUARANTEERATIO
SUBGUARANTEERATIOTOTAL += 1
}
if (thirdItem.COMMISSION_AVGRATIO && thirdItem.ADJUST_RATIO) {
SUBCOMMISSION_AVGRATIOSUM += thirdItem.COMMISSION_AVGRATIO
SUBADJUST_RATIOSUM += thirdItem.ADJUST_RATIO
SUBADJUST_RATIOTOTAL += 1
}
if (thirdItem.ADJUST_RENT) {
SUBADJUST_RENTSUM += thirdItem.ADJUST_RENT
SUBADJUST_RENTTOTAL += 1
}
if (thirdItem.MINTURNOVER) {
SUBMINTURNOVERSUM += thirdItem.MINTURNOVER
SUBMINTURNOVERTOTAL += 1
}
})
subItem.GUARANTEERATIO = subtractAndFormat(SUBGUARANTEERATIOSUM / SUBGUARANTEERATIOTOTAL) || null
subItem.COMMISSION_AVGRATIO = subtractAndFormat(SUBCOMMISSION_AVGRATIOSUM / SUBADJUST_RATIOTOTAL) || null
subItem.ADJUST_RATIO = subtractAndFormat(SUBADJUST_RATIOSUM / SUBADJUST_RATIOTOTAL) || null
subItem.ADJUST_RENT = subtractAndFormat(SUBADJUST_RENTSUM)// / ADJUST_RENTTOTAL
subItem.MINTURNOVER = subtractAndFormat(SUBMINTURNOVERSUM)// / MINTURNOVERTOTAL
}
if (subItem.GUARANTEERATIO) {
FIRSTGUARANTEERATIOSUM += subItem.GUARANTEERATIO
FIRSTGUARANTEERATIOTOTAL += 1
}
if (subItem.COMMISSION_AVGRATIO && subItem.ADJUST_RATIO) {
FIRSTCOMMISSION_AVGRATIOSUM += subItem.COMMISSION_AVGRATIO
FIRSTADJUST_RATIOSUM += subItem.ADJUST_RATIO
FIRSTADJUST_RATIOTOTAL += 1
}
if (subItem.ADJUST_RENT) {
FIRSTADJUST_RENTSUM += subItem.ADJUST_RENT
FIRSTADJUST_RENTTOTAL += 1
}
if (subItem.MINTURNOVER) {
FIRSTMINTURNOVERSUM += subItem.MINTURNOVER
FIRSTMINTURNOVERTOTAL += 1
}
})
item.GUARANTEERATIO = subtractAndFormat(FIRSTGUARANTEERATIOSUM / FIRSTGUARANTEERATIOTOTAL) || null
item.COMMISSION_AVGRATIO = subtractAndFormat(FIRSTCOMMISSION_AVGRATIOSUM / FIRSTADJUST_RATIOTOTAL) || null
item.ADJUST_RATIO = subtractAndFormat(FIRSTADJUST_RATIOSUM / FIRSTADJUST_RATIOTOTAL) || null
item.ADJUST_RENT = subtractAndFormat(FIRSTADJUST_RENTSUM)// / ADJUST_RENTTOTAL
item.MINTURNOVER = subtractAndFormat(FIRSTMINTURNOVERSUM)// / MINTURNOVERTOTAL
}
})
let fieldData: any = [
"ADJUST_RENT",
"MINTURNOVER",
"ADJUST_AMOUNT",
"GUARANTEE_MINPRICE",
"GUARANTEE_MAXPRICE",
"GUARANTEE_AVGPRICE",
"PROFIT_AMOUNT",
"REVENUE_LASTAMOUNT",
"PROFIT_TOTALAMOUNT",
]
let enumList: any = [
"SERVERPART_TYPE",
"BUSINESS_TRADE",
"BUSINESS_PTRADE",
]
let rateList: any = [
"RENT_RATIO",
"PERIOD_DEGREE",
"ADJUST_RATIO",
"GUARANTEERATIO",
"RATIOCHANGE",
"COMMISSION_RATIO",
"PROFIT_AVG",
"COMMISSION_MINRATIO",
"COMMISSION_MAXRATIO",
"COMMISSION_AVGRATIO",
]
let newPrintData: any = formatTreeData(JSON.parse(JSON.stringify(data)), fieldData, enumList, [ServerpartTypeObj, BusinessTradeIdsObj, BusinessTradeIdsObj], rateList)
setReqDetailList(newPrintData)
setUpdateTime(data[0].RECORD_DATE ? moment(data[0].RECORD_DATE).format('YYYY-MM-DD') : '')
console.log('datadatadata', data);
setTableData(data)
setTableLoading(false)
clickTableBtnRef.current = false
} else {
setTableLoading(false)
clickTableBtnRef.current = false
setTableData([])
}
}
const handleReloadTable = () => {
// clickTableBtnRef.current = true
// formRef.current?.submit();
actionTableRef.current?.reload()
}
return (
<div >
{
showLoading ?
<div
style={{
width: 'calc(100% - 48px)',
height: '100%',
background: 'rgba(0,0,0,0.1)',
position: 'fixed',
zIndex: 5,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '15px 20px 10px',
background: '#fff',
borderRadius: '8px',
width: '200px'
}}>
<Spin />
<span style={{ marginLeft: '5px' }}>...</span>
</div>
</div> : ''
}
<div className={'saleReportHideBox'} style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }}>
{
showExportTable && reqDetailList && reqDetailList.length > 0 ?
<ProTable
columns={columns}
dataSource={reqDetailList}
pagination={false}
expandable={{
defaultExpandAllRows: true
}}
/> : ''
}
</div>
<div id='hiddenBox' style={{ position: 'fixed', zIndex: -1, top: 0, left: 0 }} />
<div style={{ backgroundColor: '#fff', display: 'flex' }}>
<LeftSelectTree setSelectedId={setSelectedId} setCollapsible={setCollapsible} collapsible={collapsible} />
<div style={{
width: !collapsible ? 'calc(100% - 300px)' : 'calc(100% - 60px)',
paddingTop: 0,
paddingBottom: 0,
paddingRight: 0
}}>
<ProTable
style={{ background: '#fff' }}
scroll={{ x: "100%", y: 'calc(100vh - 510px)' }}
rowKey={(record) => {
return `${record?.SPREGIONTYPE_INDEX}-${record?.SERVERPART_ID}-${record?.BUSINESSPROJECT_ID}-${record?.PROJECT_ENDDATE}-${record?.index}`
}}
bordered
formRef={formRef}
headerTitle={<PageTitleBox props={props} />} // 列表表头
// "智能招商分析列表"
actionRef={actionTableRef}
search={{
span: 6, labelWidth: 'auto',
defaultCollapsed: false,
optionRender: ({ searchText }, { form }) => {
return [
<Button
key="reset"
onClick={() => {
formRef.current?.resetFields();
}}
>
</Button>,
<Button
key="sub"
type={'primary'}
loading={tableLoading}
onClick={() => {
clickTableBtnRef.current = true
formRef.current?.submit();
}}
>
</Button>
]
}
}}
dataSource={tableData}
loading={tableLoading}
// 请求数据
request={async (params, sorter) => {
console.log('params', params);
if (!selectedId) {
return
}
if (clickTableBtnRef.current) {
handleGetTableData(params)
} else {
if (tableData && tableData.length > 0) {
}
}
}}
columns={columns}
toolbar={{
actions: [
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
buttonText={'导出excel'}
ref={downloadBtnRef}
table="table-to-xls-BUSINESSANALYSIS"
filename={`智能招商分析`}
sheet="sheet1"
/>
</span>,
<Typography.Text type="secondary">{updateTime || ''}</Typography.Text>,
<Button
type="primary"
onClick={(e) => {
if (reqDetailList && reqDetailList.length > 0) {
setShowLoading(true)
setTimeout(() => {
setShowExportTable(true)
setTimeout(() => {
exportTable(e)
}, 100)
}, 100)
} else {
message.error('暂无数据可导出!')
}
}}
>
excel
</Button>
],
}}
columnsState={{
value: columnsStateMap,
onChange: setColumnsStateMap,
}}
onChange={(pagination, filters, sorter, extra) => {
if (sorter.field) {
const sortedData = [...tableData].sort((a, b) => {
if (sorter.order === 'ascend') {
return a[sorter.field] > b[sorter.field] ? 1 : -1;
} else {
return a[sorter.field] < b[sorter.field] ? 1 : -1;
}
});
setTableData(sortedData);
}
}}
// pagination={false}
// pagination={{ defaultPageSize: 10 }}
/>
</div>
</div>
<Drawer
width={'80%'}
visible={showNewDetail}
className={'BusinessDetail'}
onClose={() => {
setCurrentNewRow(undefined);
setShowNewDetail(false);
}}
bodyStyle={{ backgroundColor: "#f9f9f9", padding: 0 }}
closable={false}
>
{showNewDetail && <BusinessanalysisDetail searchParamsParent={searchParams} ContainHolidayType={searchParams?.ContainHoliday} fatherGetData={handleGetTableData}
currentUser={currentUser} allServerpartStr={allServerpartStr} showDetail={showNewDetail} currentRow={currentNewRow} parentRef={actionRef} reloadTable={handleReloadTable} setCurrentRow={setCurrentNewRow} />}
</Drawer>
<Drawer
width={'80%'}
visible={showDetail}
onClose={() => {
setCurrentRow(undefined);
setShowDetail(false);
}}
closable={false}
destroyOnClose
>
<InvestmentPromotionDetail parentRow={currentRow} />
{/* {currentRow?.INVESTMENTANALYSIS_ID && (
<ProDescriptions<INVESTMENTANALYSISModel>
column={2}
request={async () => ({
data: currentRow || {},
})}
params={{
id: currentRow?.INVESTMENTANALYSIS_ID,
}}
columns={columns as ProDescriptionsItemProps<INVESTMENTANALYSISModel>[]}
/>
)} */}
</Drawer>
</div>
);
};
export default connect(({ user }: ConnectState) => ({
currentUser: user.currentUser
}))(INVESTMENTANALYSISTable);