import PageContent from '@/components/PageContent'; import { Button, Tabs, Space, Drawer, Timeline, message } from 'antd'; import styles from './index.less'; import { useEffect, useMemo, useRef, useState } from 'react'; import axios from 'axios'; import { useLocation, useParams, useRequest, useSearchParams, useNavigate, useModel, } from '@umijs/max'; import { queryPsrExcel, queryPsrExcelList, queryPsrMonthDetail, queryPsrMonthLast, queryPsrMonthList, queryPsrWorkLoad, querySavePsrMonth, } from '../../services/psr'; import SaveModal from './components/saveOtherModal'; import CompareModal from './components/compareModal'; import CompareCom from './components/compareCom'; import dayjs from 'dayjs'; import { getToken } from '@/utils/utils'; import { exportExcel, getUUID } from '../../utils/exportExcl'; import { stringify } from 'qs'; import LuckyExcel from 'luckyexcel'; const ZeroNineType = { Equipment: '09-010', //设备费 Production: '09-020', //金科制造中心设备制造费 UF: '09-030', //金科制造中心-UF膜( AI: '09-040', //数字双胞胎 Install: '09-050', //安装分包费用(包括增值税) Construction: '09-060', //土建分包费用(包括增值税) }; const preActConfig = [ { type: ZeroNineType.Equipment, originC: 6, originR: { begin: 6, end: 297 }, //总的减上面所有的 fill: { c: 5, r: 36 }, num: 293, }, { type: ZeroNineType.Production, originC: 6, originR: { begin: 17, end: 27 }, //填充到psr表中的位置 fill: { c: 5, r: 37 }, num: 301, }, { type: ZeroNineType.UF, originC: 6, originR: { begin: 6, end: 16 }, fill: { c: 5, r: 38 }, num: 309, }, { type: ZeroNineType.AI, originC: 6, originR: { begin: 172, end: 192 }, fill: { c: 5, r: 39 }, num: 317, }, { type: ZeroNineType.Install, originC: 6, originR: { begin: 214, end: 224 }, fill: { c: 5, r: 40 }, num: 325, }, { type: ZeroNineType.Construction, originC: 6, originR: { begin: 214, end: 224 }, fill: { c: 5, r: 41 }, num: 333, }, { type: ZeroNineType.Equipment, originC: 8, originR: { begin: 6, end: 297 }, //总的减上面所有的 fill: { c: 3, r: 36 }, num: 291, }, { type: ZeroNineType.Production, originC: 8, originR: { begin: 17, end: 27 }, //填充到psr表中的位置 fill: { c: 3, r: 37 }, num: 299, }, { type: ZeroNineType.UF, originC: 8, originR: { begin: 6, end: 16 }, fill: { c: 3, r: 38 }, num: 307, }, { type: ZeroNineType.AI, originC: 8, originR: { begin: 172, end: 192 }, fill: { c: 3, r: 39 }, num: 315, }, { type: ZeroNineType.Install, originC: 8, originR: { begin: 214, end: 224 }, fill: { c: 3, r: 40 }, num: 323, }, { type: ZeroNineType.Construction, originC: 8, originR: { begin: 214, end: 224 }, fill: { c: 3, r: 41 }, num: 331, }, ]; const curMonthConfig = [ { type: ZeroNineType.Equipment, originC: null, originR: { begin: 6, end: 297 }, //总的减上面所有的 fill: { c: 7, r: 36 }, num: 295, }, { type: ZeroNineType.Production, originC: null, //需要计算的出,当前表单是第几月,取当月的那列 originR: { begin: 17, end: 27 }, fill: { c: 7, r: 37 }, num: 303, }, { type: ZeroNineType.UF, originC: null, originR: { begin: 6, end: 16 }, fill: { c: 7, r: 38 }, num: 311, }, { type: ZeroNineType.AI, originC: null, originR: { begin: 172, end: 192 }, fill: { c: 7, r: 39 }, num: 319, }, { type: ZeroNineType.Install, originC: null, originR: { begin: 214, end: 224 }, fill: { c: 7, r: 40 }, num: 327, }, { type: ZeroNineType.Construction, originC: null, originR: { begin: 214, end: 224 }, fill: { c: 7, r: 41 }, num: 335, }, ]; const workConfig = [ { code: '02-010', fill: { r: 7, actC: 3, curC: 7 }, // actC实际支出 curC当月发生额 }, { code: '04-010', fill: { r: 11, actC: 3, curC: 7 }, }, { code: '05-010', fill: { r: 16, actC: 3, curC: 7 }, }, { code: '06-010', fill: { r: 24, actC: 3, curC: 7 }, }, { code: '07-010', fill: { r: 28, actC: 3, curC: 7 }, }, { code: '08-010', fill: { r: 32, actC: 3, curC: 7 }, }, { code: '10-010', fill: { r: 44, actC: 3, curC: 7 }, }, { code: '11-010', fill: { r: 59, actC: 3, curC: 7 }, }, { code: '11-030', fill: { r: 61, actC: 3, curC: 7 }, }, { code: '11-050', fill: { r: 63, actC: 3, curC: 7 }, }, ]; const PSRDetail = () => { const { initialState } = useModel('@@initialState'); const user = initialState?.user || {}; const navigate = useNavigate(); const params = useParams(); const location = useLocation(); const token = getToken(); const { id: projectId } = params; const { state: { project_name, flow_id, node_id, init_flow_id }, } = location; const [historyList, setHistoryList] = useState([]); const [excelData, setExcelData] = useState(); const [historyOpen, setHistoryOpen] = useState(); const [open, setOpen] = useState(false); const [key, setKey] = useState(); const [compareOpen, setCompareOpen] = useState(false); const [compareValues, setCompareValues] = useState([]); const [isOriginVer, setIsOriginVer] = useState(false); //是否原始版本 是的话只能另存不能编辑 const luckysheetRef = useRef(); const iframeRef = useRef(); const unableEdit = (option) => { option.showtoolbar = false; option.enableAddRow = false; option.sheetFormulaBar = false; option.enableAddBackTop = false; option.showsheetbarConfig = { add: false, sheet: false, }; option.cellRightClickConfig = { copy: false, // 复制 copyAs: false, // 复制为 paste: false, // 粘贴 insertRow: false, // 插入行 insertColumn: false, // 插入列 deleteRow: false, // 删除选中行 deleteColumn: false, // 删除选中列 deleteCell: false, // 删除单元格 hideRow: false, // 隐藏选中行和显示选中行 hideColumn: false, // 隐藏选中列和显示选中列 rowHeight: false, // 行高 columnWidth: false, // 列宽 clear: false, // 清除内容 matrix: false, // 矩阵操作选区 sort: false, // 排序选区 filter: false, // 筛选选区 chart: false, // 图表生成 image: false, // 插入图片 link: false, // 插入链接 data: false, // 数据验证 cellFormat: false, // 设置单元格格式 }; }; //请求投标版、签字版psr excel // const { run: runExcel } = useRequest(queryPsrExcel, { // manual: true, // formatResult: (res) => { // if (res) { // const jsonData = JSON.parse(res); // renderSheet(jsonData); // } // }, // }); //请求月度psr和现金流列表 data_type 1 psr 2 现金流 const { // data: historyList, run: runList, loading: listLoading, } = useRequest( (data) => queryPsrMonthList({ project_id: projectId, data_type: data_type, ...data, }), { manual: true, formatResult: (res) => { if (res.code == 200) { const list = res?.data?.list?.map((item) => { let name = dayjs(item.day).format('YYYY-MM'); if (item.ver_type == 1) name = '原始版本'; if (item.ver_type == 2) name = '基础版本'; return { ...item, name }; }); setHistoryList(list); } }, }, ); //保存/另存为月度psr和现金流接口 const { run: runSave, loading: saveLoading } = useRequest( (data) => querySavePsrMonth(data), { manual: true, onSuccess: () => { message.success('保存成功'); if (open) setOpen(false); }, onError: () => { message.success('添加失败'); }, }, ); //请求月度psr和现金流详情接口 const { run: runDetail } = useRequest((data) => queryPsrMonthDetail(data), { manual: true, formatResult: (res) => { if (res?.data) { let data = res.data; let name = dayjs(data.day).format('YYYY-MM'); if (data.ver_type == 1) name = '原始版本'; if (data.ver_type == 2) name = '基础版本'; setExcelData({ ...data, name }); setHistoryOpen(false); const jsonData = JSON.parse(data.json_data); if (jsonData[0].celldata && typeof jsonData[0].celldata == 'string') jsonData[0].celldata = JSON.parse(jsonData[0].celldata); if (jsonData[0].config && typeof jsonData[0].config == 'string') jsonData[0].config = JSON.parse(jsonData[0].config); renderSheet(jsonData, data.is_edit); } }, }); //请求签字版PSR历史版本列表 const { run: run, loading: loading } = useRequest( (id) => queryPsrExcelList({ project_id: projectId, template_node_id: id, }), { manual: true, formatResult: (res) => { if (res.code == 200) { const list = res?.data?.list?.map((item) => { return { ...item, name: item.version_name }; }); setHistoryList(list); } }, }, ); // useEffect(() => { // let url = '/psrData.json'; // axios.get(url).then((res) => { // if (res.status == 200) { // renderSheet(res.data); // } // }); // }, [key]); const data_type = useMemo(() => { if (key == '3') return 1; if (key == '4') return 2; return null; }, [key]); useEffect(() => { setCompareValues([]); if (key) { onChange(key); } else { queryPsrExcel({ gridKey: node_id }); } }, [key]); //请求投标版、签字版psr excel const queryPsrExcel = (data) => { axios({ url: `/api/v1/purchase/record/sheet?${stringify(data)}`, method: 'POST', data, headers: { 'JWT-TOKEN': token, }, }).then((req) => { if (req.status == 200) { const jsonData = JSON.parse(req.data); renderSheet(jsonData); } }); }; const onChange = (key) => { if (key == '1') { queryPsrExcel({ gridKey: node_id }); } else if (key == '2') { queryPsrExcel({ gridKey: flow_id }); } else { initPsrActrual(key); } }; //请求前两个tab的数据 const initPsrActrual = async (key) => { const data_type = key == '3' ? 1 : 2; const res = await queryPsrMonthLast({ project_id: projectId, data_type }); if (res.data?.length > 0 && res.data[0].json_data) { let name = dayjs(res.data[0].day).format('YYYY-MM'); if (res.data[0].ver_type == 1) name = '原始版本'; if (res.data[0].ver_type == 2) name = '基础版本'; const isOrigin = res.data[0].ver_type == 1 ? 1 : 0; setIsOriginVer(isOrigin); setExcelData({ ...res.data[0], name }); const data = JSON.parse(res.data[0].json_data); if (data.celldata) data.celldata = JSON.parse(data.celldata); if (data.config) data.config = JSON.parse(data.config); renderSheet( Array.isArray(data) ? data : [data], isOrigin ? 0 : res.data[0].is_edit, ); } }; //另存为月版本 const handlerSaveOther = (data) => { const luckyData = luckysheetRef.current?.toJson(); //设置表单日期 const day = data.ver_type == 2 //基础版本是创建当天的日期 月版本是创建月份的最后一天 ? dayjs().format('YYYY-MM-DD') : dayjs(data.day).endOf('month').format('YYYY-MM-DD'); const celldata = luckyData?.data[0]?.celldata; const rc = key == '3' ? { r: 1, c: 1 } : { r: 1, c: 3 }; //psr日期位置是1 1 现金流日期位置是 1 3 const dateItem = celldata?.find((item) => item.r == rc.r && item.c == rc.c); if (dateItem) { dateItem.v.v = day; dateItem.v.m = day; } if (luckyData?.data) { const params = { ...data, project_id: Number(projectId), json_data: JSON.stringify(luckyData.data), data_type: data_type, }; runSave(params); } }; //保存 const handlerSave = () => { const luckyData = luckysheetRef.current?.toJson(); let allData; //如果是现金流的保存。需要计算一些数值填充到psr中; if (key == '4') { //当月发生额数据 计算当月发生额的月份 originC let newMonthConfig = [...curMonthConfig]; const celldata = luckyData.data[0].celldata; const originC = getMonthCol(celldata); if (originC || originC == 0) { newMonthConfig = curMonthConfig.map((item) => { return { ...item, originC }; }); } allData = getPsrDataByAct([...preActConfig, ...newMonthConfig]); console.log(allData); } const params = { id: excelData?.id, data_type: excelData?.data_type, project_id: excelData?.project_id, day: dayjs(excelData?.day).format('YYYY-MM-DD'), json_data: JSON.stringify(luckyData.data), psr_json_data: JSON.stringify(allData), }; console.log(params); runSave(params); }; //获取当月发生额的月份 const getMonthCol = (celldata) => { //计算出当月发生额的月份 originC const date = changeDate(excelData?.day); //转换成55078这种格式 const originC = celldata.find( (item) => item.r == 5 && Math.abs(item.v?.v - date) < 5, )?.c; return originC; }; const getPsrDataByAct = (configList) => { const luckyData = luckysheetRef.current?.toJson(); let otherValueTotal = 0; //获取除设备费之外的所有费用的和 const preValues = configList.map((item) => { const celldata = luckyData.data[0].celldata; const { type, originC, num, originR: { begin, end }, } = item; let value = 0; for (let i = begin; i <= end; i++) { const item = celldata.find((item) => item.c == originC && item.r == i); if (item?.v?.v) value += item.v.v; } if (type !== ZeroNineType.Equipment) otherValueTotal += value; return { num, value }; }); const EquPreItem = preValues.find( (item) => item.type == ZeroNineType.Equipment, ); if (EquPreItem?.value) EquPreItem.value = EquPreItem?.value - otherValueTotal; //全部的费用 减去 除设备费之外的所有费用的和 得到设备费 console.log('------预算列的值---------', preValues); return preValues; }; const exportExcl = (title) => { const luckyData = luckysheetRef.current?.toJson(); exportExcel(luckyData.data, title); }; const handlerLoad = () => { const contentWindow = iframeRef.current.contentWindow; luckysheetRef.current = contentWindow.luckysheet; }; const renderSheet = (currentData, is_edit = false) => { if (!luckysheetRef.current) { setTimeout(() => { renderSheet(currentData, is_edit); }, 500); return; } const data = currentData; //设置单元格不可编辑 data?.forEach((item) => { item.config.authority = is_edit ? null : { sheet: true, hintText: '当前excel不可编辑!', }; // 公式计算 let calcChain = []; let index = item.index; item.celldata?.forEach((cell) => { if (typeof cell.v.f !== 'undefined') { calcChain.push({ r: cell.r, c: cell.c, index, }); } }); item.calcChain = calcChain; }); let option = { lang: 'zh', showinfobar: false, showstatisticBar: false, permissions: user?.Permission, data: JSON.parse(JSON.stringify(data)), hook: { cellMousedown: (cell, position, sheet) => { console.log(cell, sheet); }, cellUpdated: () => { luckysheetRef.current.refreshFormula(); }, workbookCreateAfter: async () => { //当前为为终版psr标签并且可编辑状态时填充人日数据 if (key == '3' && is_edit) { fillWorkLoadData(); // const res = await queryPsrWorkLoad({ project_id: projectId }); // if (res?.data) { // console.log('--------------------', res.data); // luckysheetRef.current.setCellValue(8, 4, res.data.Total); // luckysheetRef.current.setCellValue(8, 8, res.data.Month); // } } }, }, }; option.data.forEach((item) => { delete item.data; if (item.celldata) { item.celldata.forEach((cell) => { // 生成uuid if (!cell.v.cid) cell.v.cid = getUUID(); }); } // 默认禁止编辑 // item.config.authority = { sheet: true, hintText }; }); console.log(option.data); //设置不可编辑 if (!is_edit) unableEdit(option); luckysheetRef.current.destroy(); luckysheetRef.current.create(option); }; const fillWorkLoadData = async () => { const param = { project_id: projectId }; param.code = workConfig.map((item) => item.code).join(','); param.s_time = dayjs('2023-01').startOf('month').format('YYYY-MM-DD'); param.e_time = dayjs('2023-07').endOf('month').format('YYYY-MM-DD'); const res = await queryPsrWorkLoad(param); if (res?.data) { const data = { '02-010': [800, 100] }; Object.keys(data).forEach((code) => { const list = data[code]; //第一个是当月的,第二个是累计的 const fill = workConfig.find((item) => item.code == code)?.fill; if (list?.length > 0 && fill) luckysheetRef.current.setCellValue(fill.r, fill.curC, list[0]); luckysheetRef.current.setCellValue(fill.r, fill.actC, list[1]); }); console.log('--------------------', res.data); // luckysheetRef.current.setCellValue(8, 4, res.data.Total); // luckysheetRef.current.setCellValue(8, 8, res.data.Month); } }; const renderTitle = (data_type, title) => { if (compareValues?.length == 2) { return (
); } if (data_type == 0) //投标版psr return (
); if (data_type == 3) //签字版psr return (
当前PSR表单: {excelData?.name}
); //过程/终版psr 现金流 return (
当前PSR表单: {excelData?.name}
); }; const changeDate = (date) => { date = dayjs(date); const startDate = dayjs('1900-01-01'); const daysDifference = date.diff(startDate, 'day'); return daysDifference; }; const items = [ { key: '1', label: '投标版PSR', children: renderTitle(0, '投标版PSR'), }, { key: '2', label: '签字版PSR', children: renderTitle(3, '签字版PSR'), }, { key: '3', label: '过程/终版PSR', children: renderTitle(1, '过程/终版PSR'), }, { key: '4', label: '现金流', children: renderTitle(2, '现金流'), }, ]; // const handlerOnChange = (event) => { // console.log(event); // console.log('----------------', luckysheetRef.current); // var file = event.target.files[0]; // var fileName = file.name; // fileName = fileName + ''; // //將文件加載到頁面上 // LuckyExcel.transformExcelToLucky( // file, // function (exportJson, luckysheetfile) { // if (exportJson.sheets == null || exportJson.sheets.length == 0) { // alert( // 'Failed to read the content of the excel file, currently does not support xls files!', // ); // return; // } // console.log(exportJson, luckysheetfile); // renderSheet(exportJson?.sheets); // // window.luckysheet.destroy(); // // window.luckysheet.create({ // // container: 'luckysheet', //luckysheet is the container id // // showinfobar:false, // // lang: 'zh', // 设定表格语言 // // allowEdit: true,//作用:是否允许前台编辑 // // // allowUpdate: true, // // allowCopy: true, //是否允许拷贝 // // showtoolbar: true, //是否第二列显示工具栏 // // showinfobar: true, //是否显示顶部名称栏 // // showsheetbar: true, //是否显示底部表格名称区域 // // showstatisticBar: true, //是否显示底部计数栏 // // pointEdit: false, //是否是编辑器插入表格模式 // // pointEditUpdate: null, //编辑器表格更新函数 // // data:exportJson.sheets, // // title:exportJson.info.name, // // userInfo:exportJson.info.name.creator, // // functionButton: '', // // }); // }, // ); // }; const handlerDetailClick = (id) => { if (key == '2') { queryPsrExcel({ gridKey: id }); setHistoryOpen(false); return; } runDetail({ id }); }; return (
{/* */} {project_name}
{compareValues?.length == 2 ? ( ) : (