import React, { useEffect, useState, useRef, useMemo } from 'react'; import { UnorderedListOutlined, PlusOutlined } from '@ant-design/icons'; import { Button, Modal, message, Alert, Avatar, Spin, Select, Menu, Dropdown } from 'antd'; import { connect } from 'dva'; import styles from './Index.less'; import LuckySheet from './LuckySheet'; import router from 'umi/router'; import AuditModal from './AuditModal'; // import CommentDrawer from './CommentDrawer'; import RightDrawer from './RightDrawer'; import CommitModal from './CommitModal'; import CompareModal from './CompareModal'; import ExportModal from './ExportModal'; import FlowModal from './FlowModal'; import HistoryModal from './HistoryModal'; import TimeNode from './TimeNode'; import FilesModal from './FilesModal'; import VersionModal from './VersionModal'; import CommitAuditModal from './CommitAuditModal'; import CommentContent from '@/components/CommentContent'; import MergeModal from './MergeModal'; import { GetTokenFromUrl, getToken } from '@/utils/utils'; import { queryDetail } from '@/services/boom'; const LocalData = localStorage.luckysheet; const { Option } = Select; function Detail(props) { const { // flow, dispatch, comment, history, loading, currentUser, fileList, roleList, template, versionList, auditList, flowDetail, match: { params }, } = props; // const audit_status = 0 const [commentVisible, setCommentVisible] = useState(false); const [mergeVisible, setMergeVisible] = useState(false); const [compareVisible, setCompareVisible] = useState(false); const [exportVisible, setExportVisible] = useState(false); const [commitVisible, setCommitVisible] = useState(false); const [auditVisible, setAuditVisible] = useState(false); const [flowVisible, setFlowVisible] = useState(false); const [versionVisible, setVersionVisible] = useState(false); const [commitAuditVisible, setCommitAuditVisible] = useState(false); const [sheet, setSheet] = useState({}); const [compareList, setCompareList] = useState([]); const [edit, setEdit] = useState(false); const [isMerge, setIsMerge] = useState(false); const [version, setVersion] = useState({}); const [user, setUser] = useState([]); const [updateCount, setUpdateCount] = useState({ diff: 0, add: 0, }); const [fileVisible, setFileVisible] = useState(false); const [exportDate, setExportData] = useState([]); // const [dataSource, setDataSource] = useState(DataSource); // const [lastCommit, setLastCommit] = useState({ data: [] }); const sheetRef = useRef(); const sheetRef2 = useRef(); const sheetRef3 = useRef(); const fileRef = useRef(); const statusRef = useRef({ edit: false, compare: false, }); const cellPosition = useRef({}); // const [excelId, setExcelId] = useState(parseInt(params.excelId)); // const excelId = parseInt(params.excelId); const projectId = parseInt(params.projectId); const templateId = parseInt(params.templateId); const flow = useMemo(() => { let data = { active: 0, active_id: null, current: 0, currentNode: {}, list: { FlowNodes: [], }, }; if (version?.flow_id && auditList?.length > 0) { let item = auditList.find(item => item.list.id == version.flow_id); if (!item) return data; // 合并同审批级别项 let nodes = {}; item.list.FlowNodes.map(item => { if (!nodes[item.seq]) nodes[item.seq] = { ...item, user: [] }; nodes[item.seq].user.push(item.AuditorUser); }); item.list.FlowNodes = Object.values(nodes); // 查询当前节点 let current = item.list.FlowNodes.findIndex(node => node.seq == item.active); item.current = current == -1 ? 0 : current; // 保存当前所处节点 item.currentNode = item.list.FlowNodes[item.current]; data = item; } return data; }, [auditList, version]); const audit_status = flow.active_audit; const isAuditor = useMemo(() => { const getUserRole = () => { let item = flow.currentNode?.user?.find?.(item => item.ID == currentUser.ID); if (item) return true; return false; }; return audit_status == 1 && getUserRole(); }, [audit_status, flow, currentUser]); // const audit_status = 1; const onSave = () => { let sheet1 = compareList[0]; Modal.confirm({ title: '提示', content: `是否确认保存【${sheet1.version_name || sheet1.name}】`, okText: '确定', cancelText: '取消', onOk() { let sheetData = sheetRef3.current.getSheetJson().data; sheetData.forEach(sheet => { delete sheet.data; }); let params = { ...sheet1, data: JSON.stringify(sheetData), }; dispatch({ type: 'detail/commitSheet', payload: params, callback: () => { onCompare(false); }, }); }, }); }; const onCompare = async checkSheets => { if (checkSheets) { const [sheet1, sheet2] = checkSheets; if (!sheet1.data) { sheet1.data = ( await queryDetail({ excel_id: sheet1.id, }) ).data; } if (!sheet2.data) { sheet2.data = ( await queryDetail({ excel_id: sheet2.id, }) ).data; } setCompareList(checkSheets); statusRef.current.compare = true; } else { let index = compareList.findIndex(item => item.id == sheet.id); // 退出比对模式 if (index == 0) { sheetRef3.current.toggleCompare(false); } else if (index == 1) { sheetRef2.current.toggleCompare(false); } setIsMerge(false); setCompareList([]); setSheet({ ...sheet, }); setUpdateCount({ diff: 0, add: 0, }); statusRef.current.compare = false; } setCommentVisible(false); }; // const exportSheet = async item => { // console.log(item); // var sheets = await queryHistoryDetail(item); // sheets.id = sheets.sheet_id; // setSheet({ // ...item, // name: item.version_name, // data: sheets, // }); // }; const renderSheetDom = (item, index) => { return (

{item?.name} {item.version_name && `(${item.version_name})`}

); }; const onClickCell = (cell, position, s) => { console.log(cell); if (cell?.cid && !statusRef.current.edit) { let payload = { sheet_id: s.order || '0', excel_id: version.id, cid: cell.cid, }; dispatch({ type: 'detail/queryComment', payload, }); cellPosition.current = { ...payload, sheet_index: (s.seq || 0) + '', }; // setCommentVisible(true); } // 比对模式下双excl同步选中 // if (statusRef.current.compare) { // sheetRef3.current.selectCell(position.r, position.c, s.order); // sheetRef2.current.selectCell(position.r, position.c, s.order); // } }; const onCommit = (values, id) => { let currentData = sheetRef.current.getSheetJson().data; let sheets = JSON.parse(JSON.stringify(currentData)); sheets.forEach(item => { delete item.data; }); console.log(sheets); let params = { ...values, id: id, project_id: version.project_id, name: version.name, guid: version.guid, audit_status: version.audit_status, template_id: version.template_id, template_node_id: version.template_node_id, flow_id: version.flow_id, node_id: version.node_id, new_version: '0', data: JSON.stringify(sheets), }; dispatch({ type: 'detail/commitSheet', payload: params, callback: sheets => { onCompare(false); setCommitVisible(false); setVersionVisible(false); // setSheet(sheets); // localStorage.luckysheet = JSON.stringify(sheets); }, }); }; const onUpdate = () => { let currentData = sheetRef.current.getSheetJson().data; let sheets = JSON.parse(JSON.stringify(currentData)); sheets.forEach(item => { delete item.data; }); console.log(sheets); let params = { ...version, data: JSON.stringify(sheets), }; dispatch({ type: 'detail/saveSheet', payload: params, }); }; // const onCommit = values => { // var flowNode = flow.currentNode; // // 获取最新sheet页信息 // dispatch({ // type: 'detail/querySheet', // payload: { // project_id: projectId, // flow_id: flowNode.flow_id, // node_id: flowNode.id, // }, // callback: sheets => { // let currentData = sheetRef.current.getSheetJson().data; // currentData.forEach((item, index) => { // // 使用最新的sheetId 防止多次创建sheet // item.id = sheets.data[index]?.id; // console.log(item.data.celldata); // }); // let newSheet = { // ...values, // data: JSON.stringify(currentData), // id: excelId, // flow_id: flowNode.flow_id, // node_id: flowNode.id, // project_id: projectId, // }; // dispatch({ // type: 'detail/commitSheet', // payload: newSheet, // callback: sheets => { // onCompare(false); // setCommitVisible(false); // setSheet(sheets); // localStorage.luckysheet = JSON.stringify(sheets); // }, // }); // }, // }); // }; const onAudit = ({ audit_comment }) => { var flowNode = flow.currentNode; dispatch({ type: 'detail/approve', payload: { id: version.id, project_id: projectId, audit_status: 2, flow_id: flowNode.flow_id, node_id: flowNode.seq, audit_comment, }, callback: () => { setAuditVisible(false); }, }); }; const onSubmitAudit = () => { Modal.confirm({ title: '提示', content: '是否确认提交审批。', okText: '确定', cancelText: '取消', onOk() { var flowNode = flow.currentNode; dispatch({ type: 'detail/submitAudit', payload: { id: version.id, flow_id: flowNode.flow_id, node_id: flowNode.id, projectId, }, }); }, }); }; const onApprove = flag => { if (!flag) { setAuditVisible(true); return; } Modal.confirm({ title: '提示', content: `是否${flag ? '通过' : '拒绝'}审批。`, okText: '确定', cancelText: '取消', onOk: () => { var flowNode = flow.currentNode; dispatch({ type: 'detail/approve', payload: { id: flow.active_id, project_id: projectId, audit_status: flag ? 3 : 2, flow_id: flowNode.flow_id, node_id: flowNode.seq, }, callback: newVersion => { // 更新flow流程图 dispatch({ type: 'xflow/queryBoomFlowDetail', payload: { id: templateId, }, }); if (flow.current == flow.list.FlowNodes.length - 1) { // 最后一个审核节点通过后 需要更新version id localStorage.excelId = newVersion.id; setVersion({ ...version, id: newVersion.id, }); } }, }); }, }); }; const onMerge = () => { const [sheet1, sheet2] = compareList; Modal.confirm({ title: '提示', content: `是否确认将【${sheet2.version_name}】改动的内容同步至【${sheet1.version_name || sheet1.name}】`, okText: '确定', cancelText: '取消', onOk() { // let sheet2Data = sheetRef2.current.getSheetJson() sheetRef3.current.mergeExcl(sheetRef2.current.updateCell); // setCompareList([...compareList]); // let currentData = sheetRef3.current.getSheetJson() // // 更新后重新比对 // sheetRef2.current.toggleCompare(false); // sheetRef2.current.toggleCompare(true, currentData); }, }); }; const onMergeVersion = async sheet2 => { // const [sheet1, sheet2] = checkSheets; const sheet1 = version; if (!sheet1.data) { sheet1.data = ( await queryDetail({ excel_id: sheet1.id, }) ).data; } if (!sheet2.data) { sheet2.data = ( await queryDetail({ excel_id: sheet2.id, }) ).data; } setIsMerge(true); setCompareList([sheet1, sheet2]); // setTimeout(() => { // sheetRef3.current.mergeExcl(sheet.data); // }, 400); }; // const handleClickCommit = async () => { // const { list } = await queryHistory(); // let lastCommit = list[0]; // // 判断当前版本是否为最新版本 // if (lastCommit && sheet.guid != lastCommit.guid) { // Modal.confirm({ // title: '提示', // content: '当前版本与最新版本不匹配,将进入比对模式确认版本差异。', // okText: '比对', // cancelText: '返回', // onOk() { // dispatch({ // type: 'detail/queryHistoryDetail', // payload: { // excel_id: lastCommit.excel_id, // history_id: lastCommit.id, // }, // callback: sheets => { // setIsMerge(true); // let currentSheet = { // ...sheet, // name: '当前版本', // }; // let lastSheet = { // ...lastCommit, // name: `线上最新版本(${lastCommit.version_name})`, // data: sheets, // }; // onCompare([currentSheet, lastSheet]); // }, // }); // }, // }); // } else { // setCommitVisible(true); // } // setCommentVisible(false); // }; // const handleEdit = status => { // if (!status) { // // 还原数据 // sheetRef.current.renderSheet(sheet.data); // } // setCommentVisible(false); // setEdit(status); // statusRef.current.edit = status; // sheetRef.current.toggleEdit(status); // }; const handleClickFile = () => { fileRef.current.click(); }; const handleMenuClick = e => { console.log('click', e); switch (e.key) { case 'back': // 返回 router.push(`/home`); break; // case 'version': // // 版本 // queryHistory(); // setCommentVisible(false); // setHistoryVisible(true); // break; case 'bomDetail': // 版本 setCommentVisible(true); break; case 'export': // 导出 handleExportClick(); break; case 'commitAudit': // 提交流转 setCommitAuditVisible(true); break; case 'flow': // 查看流程 setFlowVisible(true); break; case 'compare': // 比对 setCompareVisible(true); break; case 'template': // 模板 handleClickFile(); break; // case 'auditSuccess': // // 审核通过 // onApprove(true); // break; // case 'auditFailed': // // 审核拒绝 // onApprove(false); // break; // case 'edit': // // 编辑 // handleEdit(true); case 'merge': // 同步版本 setMergeVisible(true); break; case 'commit': // 提交 // handleClickCommit(); setCommitVisible(true); setCommentVisible(false); break; case 'approval': // 申请审批 onSubmitAudit(); break; case 'attachment': // 附件 setFileVisible(true); queryFiles(); break; } }; const renderBtns = () => { // if (edit) { // return ( // <> // // // // ); // } // 判断是否为比对模式 if (compareList.length == 2) { // 判断是否为同步最新版本的比对 if (isMerge) { return ( <> {/* */} ); } else { return ; } } const menuList = [ 返回, 详情, 导出, 提交流转, 查看流程, 比对, 附件, ]; // if (audit_status != 1) { // menuList.push(历史提交); // // menuList.push(模板); // } if (!isAuditor && canEdit()) { // menuList.push(编辑); menuList.push(同步); // menuList.push(提交); // if (history.list.length > 0) { // menuList.push(申请审批); // } } return ( <> {menuList}}> {/* */} ); }; const canEdit = () => { if (flow.list.FlowNodes.length - 1 == flow.current && audit_status == 3) return false; return audit_status != 1; }; const renderAlert = () => { const audit_comment = history.list[0]?.audit_comment; let item = ''; switch (audit_status) { case 0: return; case 1: item = ; break; case 2: item = ( ); break; case 3: item = ; break; } return
{item}
; }; const exportExcl = files => { sheetRef.current.uploadExcel(files, () => { fileRef.current.value = null; }); }; const getRowOneList = () => { const obj = sheetRef.current.getSheetJson(); console.log(obj); const list = []; obj.data.forEach(item => { list.push(item.data[0]); }); return list; }; //点击导出弹出选择导出列弹框 const handleExportClick = () => { setExportData(sheetRef.current.getSheetJson()); setExportVisible(true); }; const downloadExcel = checkValue => { sheetRef.current.downloadExcel(checkValue); setExportVisible(false); }; const queryHistory = id => { return new Promise(reslove => { dispatch({ type: 'detail/queryHistory', payload: { // excel_id: id || excelId, project_id: projectId, }, callback: reslove, }); }); }; const queryFiles = () => { dispatch({ type: 'detail/queryFiles', payload: { // excel_id: id || excelId, excel_id: version.id, }, }); }; const getUploadProps = () => { const token = getToken() || GetTokenFromUrl(); const uploadProps = { name: 'file', showUploadList: false, action: `/api/v1/purchase/attachment/${version.id}`, headers: { 'JWT-TOKEN': token, }, onChange(info) { if (info.file.status !== 'uploading') { console.log(info.file, info.fileList); } if (info.file.status === 'done') { message.success(`${info.file.name} 文件上传成功`); queryFiles(); } else if (info.file.status === 'error') { message.error(`${info.file.name} 文件上传失败`); } }, }; return uploadProps; }; const deleteFile = id => { dispatch({ type: 'detail/deleteFiles', id: id, callback: () => { queryFiles(); }, }); }; const queryHistoryDetail = async item => { return new Promise(resolve => { dispatch({ type: 'detail/queryHistoryDetail', payload: { excel_id: item.excel_id, history_id: item.id, }, callback: sheet => { resolve(sheet); }, }); }); }; const getLoading = () => { let effects = loading.effects; return !loading.effects['detail/queryComment'] && loading.models.detail; }; const getFilesLoading = () => { let effects = loading.effects; return loading.effects['detail/queryFiles']; }; const downloadFile = record => { window.location.href = `${record.url}`; }; const changeVersion = id => { let version = versionList.find(item => item.id == id); if (!version) return; localStorage.excelId = id; setVersion(version); // 查询excel内容 // dispatch({ // type: 'detail/queryRecord', // payload: { // project_id: projectId, // template_id: version.template_id, // template_node_id: version.template_node_id, // version_id: version.id, // }, // callback: sheets => { // console.log(sheets); // setSheet(sheets); // // sheetRef.current.renderSheet(sheets.data); // }, // }); // // 查询历史修改 // dispatch({ // type: 'detail/queryHistoryList', // payload: { // version_id: version.id, // }, // }); // 判断是否审批节点 if (version.flow_id) { dispatch({ type: 'detail/queryAuditList', payload: { template_id: version.template_id, template_node_id: version.template_node_id, flow_id: version.flow_id, version_id: version.id, }, }); } }; const onSubmitNextNode = values => { dispatch({ type: 'detail/submitNextNode', payload: values, callback: () => { setCommitAuditVisible(false); }, }); }; const getUser = user => { setUser(user); }; const renderNode = () => { const nodeId = version.template_node_id; if (!flowDetail?.nodes || !nodeId) return; const node = flowDetail.nodes.find(item => item.Id == nodeId); return `当前节点:${node?.label || '-'}`; }; const handleSubmitCell = (value, callback) => { if (!value) return; dispatch({ type: 'detail/addComment', payload: { ...cellPosition.current, comment: value, }, callback, }); }; useEffect(() => { dispatch({ type: 'detail/queryProjectRecord', payload: { project_id: projectId, }, }); dispatch({ type: 'xflow/queryBoomFlowDetail', payload: { id: templateId, }, }); dispatch({ type: 'user/fetchUserList', }); // 审批流程 // dispatch({ // type: 'detail/queryAuditList', // }); // 查询节点 // dispatch({ // type: 'detail/queryFlowInfo', // payload: { // projectId, // }, // callback: async ({ currentNode }, sheets) => { // if (sheets.id != excelId) { // // 更新excel id // router.push(`/home/detail/${sheets.id}/${projectId}`); // } // let { list } = await queryHistory(sheets.id); // let sheet = JSON.parse(LocalData || '{}'); // if ( // LocalData && // sheet.excel_id == sheets.id && // currentNode.id == sheet.node_id && // list[0]?.audit_status != 1 // ) { // // 显示缓存数据 // setSheet(sheet); // } else { // sheets.excel_id = sheets.id; // sheets.name = sheets.version_name; // delete sheets.id; // setSheet(sheets); // } // sheetRef.current.renderSheet(sheets.data); // }, // }); // dispatch({ // type: 'detail/getRoleList', // payload: { // ID: projectId, // }, // }); }, []); useEffect(() => { if (compareList.length == 2) { const callback = ({ diff, add }) => { setUpdateCount(updateCount => { return { diff: diff.length, add: updateCount.add + add.length, }; }); }; var update1 = sheetRef3.current.toggleCompare(true, compareList[1].data, callback); var update2 = sheetRef2.current.toggleCompare(true, compareList[0].data, callback); } }, [compareList]); useEffect(() => { if (versionList.length == 0) return; if (!version.id) { const excelId = localStorage.excelId; changeVersion(excelId); } else { changeVersion(version.id); } // else if (version.id != params.excelId) { // changeVersion(version.id); // } }, [versionList]); return ( {/* */}
{/* 当前节点: {version.template_node_id}
当前状态:{version.audit_status} */} {flow?.active == 0 && ( )} {renderNode()}
{user.map(item => ( {item.Name} ))} {renderBtns()}
exportExcl(e.target.files)} />
{renderAlert()} {/* 判断是否为比对模式 */} {compareList.length == 2 ? ( <>
{compareList.map(renderSheetDom)}
) : (
{version.id && ( )}
)} setCommentVisible(false)} /> {/* setHistoryVisible(false)} onSelect={item => exportSheet(item)} /> */} setCompareVisible(false)} onOk={onCompare} /> setMergeVisible(false)} onOk={onMergeVersion} /> setExportVisible(false)} onOk={downloadExcel} /> {/* setCommitVisible(false)} onOk={values => onCommit(values, version.id)} /> */} setFlowVisible(false)} version={version} // onOk={onCommit} onChangeVersion={version => changeVersion(version.id)} /> setAuditVisible(false)} onOk={onAudit} /> setFileVisible(false)} uploadProps={getUploadProps()} DeleteFile={deleteFile} downloadFile={downloadFile} data={fileList} /> setVersionVisible(false)} onOk={values => onCommit(values)} /> setCommitAuditVisible(false)} onOk={onSubmitNextNode} />
); } export default connect(({ detail, user, xflow, loading }) => ({ flow: detail.flow, flowDetail: xflow.flowDetail, auditList: detail.auditList, fileList: detail.fileList, history: detail.history, comment: detail.comment, currentUser: user.currentUser, roleList: detail.roleList, versionList: detail.versionList, loading, }))(Detail);