HTML
<!DOCTYPE html> <html lang="en"> <link> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>生产监控</title> <link rel="stylesheet" href="https://unpkg.com/antd@3.9.3/dist/antd.min.css" /> <link rel="stylesheet" href="/css/jiankongindex.css"> </link> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script> <script src="https://unpkg.com/antd@3.9.3/dist/antd.min.js"></script> <script src="/js/jquery.1.10.min.js"></script> <script src="/js/appjs/shengchan/changeShifts/contant.js"></script> </head> <body> <div id="root"></div> <script th:inline="javascript" type="text/babel"> let collect = [[${collect}]]; let changeShifts = [[${changeShifts}]]; const ProductionMonitoring = () => { 'use strict'; let disposeArray = []; const { useState, useEffect, useRef } = React; const [someDay, setSomeDay] = useState(new Date()); const [startWorkshop, setStartWorkshop] = useState(''); const [maintenanceWorkshop, setMaintenanceWorkshop] = useState(''); const [footerDomWidth, setFooterDomWidth] = useState(''); const tableDOM = useRef(null); const [selectValue, setSetlectValue] = useState(''); const [date, setDate] = useState(''); const [searchData, setSearchData] = useState([]); useEffect(() => { setStartWorkshop(changeShifts?.yproductionlog); setMaintenanceWorkshop(changeShifts?.wproductionlog); }, []); useEffect(() => { curstomFontColor(); if (tableDOM.current) { countFootWidth() } windowResizeTableFooterWidth() const rableBodyContainer = tableDOM.current.getPopupContainer().querySelector('.ant-table-tbody').children; for (let i = 0; i < rableBodyContainer.length; i++) { const trItem = rableBodyContainer[i]; const children = trItem.children; for (let j = 0; j < children.length; j++) { const childElement = children[j]; if (j === 1 || j === 2 || j === 4 || j === 5) { childElement.style.backgroundColor = 'rgb(7,33,75)' } } } }, [searchData, setSearchData]); const isToday = (date) => { const today = new Date(); return today.getFullYear() === date.getFullYear() && today.getMonth() === date.getMonth() && today.getDate() === date.getDate() }; const replaceString = (str) => { const lastChar = str.slice(-1); switch (lastChar) { case "0": return str.replace(lastChar, ": 停止"); case "1": return str.replace(lastChar, ": 运行"); case "2": return str.replace(lastChar, ": 故障"); default: return str; } }; const concatArray = (arr_one, arr_two) => { let concatedArray = []; for (let i = 0; i < arr_one.length; i++) { if (arr_one[i].name1 || arr_one[i].name2) { for (let j = 0; j < arr_one[i].name1.length; j++) { arr_one[i].name1[j] = replaceString(arr_one[i].name1[j]) } for (let j = 0; j < arr_one[i].name2.length; j++) { arr_one[i].name2[j] = replaceString(arr_one[i].name2[j]) } } } disposeArray = arr_one; for (let i = 0; i < 5; i++) { let startIndexOne = JSON.parse(JSON.stringify(disposeArray[i])); let startIndexTwo = JSON.parse(JSON.stringify(arr_two[i])); concatedArray.push({ ...startIndexOne, ...startIndexTwo }); } for (let i = 0; i < concatedArray.length; i++) { const concatStringOne = concatedArray[i].name1.reduce((acc, curr, index) => { return acc + curr + (index < concatedArray[i].name1.length - 1 ? '、' : ''); }, ''); const concatStringTwo = concatedArray[i].name2.reduce((acc, curr, index) => { return acc + curr + (index < concatedArray[i].name2.length - 1 ? '、' : ''); }, ''); concatedArray[i].name1 = concatStringOne; concatedArray[i].name2 = concatStringTwo; } return concatedArray; }; const countFootWidth = () => { const footDomWidth = tableDOM.current.getPopupContainer().querySelector('.ant-table-row').children[0].offsetWidth setFooterDomWidth(footDomWidth); }; const windowResizeTableFooterWidth = () => { const handleResize = () => { countFootWidth(); }; window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }; const selectChange = (e) => { setSetlectValue(e) }; const dateChange = (e) => { let newDate = new Date(e._d); setSomeDay(newDate); let selectDateValue = newDate.getFullYear() + '-' + ((newDate.getMonth() + 1) < 10 ? '0' + (newDate.getMonth() + 1) : newDate.getMonth() + 1 ) + '-' + (newDate.getDate() < 10 ? '0' + newDate.getDate() : newDate.getDate()); setDate(selectDateValue) }; const submitTable = () => { if (!selectValue) return alert("类型为必填项"); if (!date) return alert("时间为必填项"); $.ajax({ type: "POST", url: "/shengchan/changeShifts/update", data: JSON.stringify({ id: changeShifts.id, yproductionlog: startWorkshop, wproductionlog: maintenanceWorkshop }), contentType: 'application/json;charset=utf-8', }) }; const onSearch = async () => { await $.ajax({ type: "POST", url: "/shengchan/changeShifts/search", data: JSON.stringify({id: changeShifts.id, datadate: date, atype: selectValue}), contentType : 'application/json;charset=utf-8', }).then(res => { if ( Array.isArray(res?.collect)) { const beforeClearArray = edTableColumnInnerHtml(edTableColumnInnerHtml(concatArray(res.collect, TABLE_DATA), 1), 2).slice(); setSearchData([{a: ''}]); setSearchData(beforeClearArray); } }); }; const curstomFontColor = () => { let tableColumnDOM = tableDOM.current?.getPopupContainer()?.querySelectorAll('td'); tableColumnDOM.forEach((node) => { let handleData = handlerNodeStr(node.innerHTML.slice("、")); node.innerHTML = handleData; }); }; const handlerNodeStr = (node) => { return node.replace(/</g, "<").replace(/>/g, ">"); }; const edTableColumnInnerHtml = (d, index) => { for (let i = 0; i < d.length; i++) { let splitArr = d[i][(`name${index}`)].split("、"); for (let j = 0; j < splitArr.length; j++) { if (splitArr[j].slice(-2) === "运行") { splitArr[j] = splitArr[j].replace(splitArr[j].slice(-2), `<span style="color: green">${splitArr[j].slice(-2)}</span>`) } else if (splitArr[j].slice(-2) === "故障") { splitArr[j] = splitArr[j].replace(splitArr[j].slice(-2), `<span style="color: orange">${splitArr[j].slice(-2)}</span>`) } else if (splitArr[j].slice(-2) === "停止") { splitArr[j] = splitArr[j].replace(splitArr[j].slice(-2), `<span style="color: red">${splitArr[j].slice(-2)}</span>`) } } d[i][`name${index}`] = splitArr.join("、"); } return d; }; const FootDom = () => { return ( <> <div className="footer-container"> <div className="footer-item" style={{ width: `${footerDomWidth}px`, borderRight: '1px solid #eee' }} > <span className="content"> {FOOTER_OPERATION} </span> </div> <div style={{ flex: 1 }}> <antd.Input value={startWorkshop} className="w1 h1" placeholder="请输入" onChange={(e) => setStartWorkshop(e.target.value)} /> </div> </div> <div className="footer-container"> <div className="footer-item" style={{ width: `${footerDomWidth}px`, borderRight: '1px solid #eee' }}> <span className="content"> {FOOTER_MAINTENANCE} </span> </div> <div style={{ flex: 1 }}> <antd.Input value={maintenanceWorkshop} className="w1 h1" placeholder="请输入" onChange={(e) => setMaintenanceWorkshop(e.target.value)} /> </div> </div> </> ) }; return ( <div className="table-container"> <antd.Table ref={tableDOM} pagination={false} columns={COLUMNS} dataSource={searchData.length > 0 ? searchData : (edTableColumnInnerHtml(edTableColumnInnerHtml(concatArray(collect, TABLE_DATA), 1), 2))} footer={() => FootDom()} /> <div className="operate-table"> <div className="operate-item"> <antd.DatePicker className="i1" onChange={dateChange} placeholder="选择日期" /> <antd.Select value={selectValue} onChange={selectChange} className="w1 i1"> <Option value="白班">白班</Option> <Option value="夜班">夜班</Option> </antd.Select> <antd.Button className="w1 i1" type="primary" size="large" onClick={onSearch}>< img src="/img/search.png" className="icon" />搜索</antd.Button> {isToday(someDay) && ( <antd.Button className="w1 i1" type="primary" size="large" onClick={submitTable}>< img src="/img/submit.png" className="icon" />提交</antd.Button> )} </div> </div> </div> ) }; const container = document.getElementById('root'); ReactDOM.render(<ProductionMonitoring />, container) </script> </body> </html>
js
const COLUMNS = [ { title: '工艺段', dataIndex: 'gyd1', key: 'gyd1', align: 'center' }, { title: '项目', dataIndex: 'xm1', key: 'xm1', align: 'center' }, { title: '记录', dataIndex: 'name1', key: 'name1', align: 'center' }, { title: '工艺段', dataIndex: 'gyd2', key: 'gyd2', align: 'center' }, { title: '项目', dataIndex: 'xm2', key: 'xm2', align: 'center' }, { title: '记录', dataIndex: 'name2', key: 'name2', align: 'center' } ] const TABLE_DATA = [ { key: '1', gyd1: '一二期脱水机房', xm1: '一二期脱水机、状态', // name1: '', gyd2: '聚铁加药间', xm2: '聚铁加药间、状态', // name2: '' }, { key: '2', gyd1: '聚铁加药间', xm1: '聚铁加药间、状态', // name1: '', gyd2: '一二期浓缩池', xm2: '剩余污泥泵、状态', // name2: '' }, { key: '3', gyd1: '消化池', xm1: '阀门、状态', // name1: '', gyd2: '三期浓缩池', xm2: '排泥泵、状态', // name2: '' }, { key: '4', gyd1: '污泥浓缩机', xm1: '污泥浓缩机、状态', // name1: '', gyd2: '一、二期剩余污泥泵', xm2: '一、二期剩余污泥泵、状态', // name2: '' }, { key: '5', gyd1: '污泥料仓液位', xm1: '污泥料仓液位、状态', // name1: '', gyd2: '脱水机房', xm2: '柱塞泵、皮带机、螺旋、状态', // name2: '' } ] const FOOTER_OPERATION = '运行车间、交班内容' const FOOTER_MAINTENANCE = '维护车间、交班内容'
css
.ant-table-thead > tr > th { color: #aadbfa; background-color: #2b5689; border-right: 1px solid #eee; border-bottom: 1px solid #eee; } .ant-table-tbody > tr > td { height: 80px; color: #aadbfa; background-color: #2b5689; border-right: 1px solid #eee; border-bottom: 1px solid #eee; } .footer-container { display: flex; min-height: 80px; color: #aadbfa; border-right: 1px solid #eee; border-bottom: 1px solid #eee; background-color: #2b5689; } .ant-input { color: #fff; background-color: rgb(7,33,75); } .footer-container .footer-item { position: relative; max-height: 100px; text-align: center; } .footer-container .footer-item .content { display: inline-block; width: 100%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .ant-table-footer { padding: 0 !important; border-top: 0 !important; } .table-container { display: flex; } .table-container .ant-table-wrapper { flex: 1; } .table-container .operate-table { padding: 8px; min-width: 150px; max-width: 150px; color: #aadbfa; background-color: #2b5689; border-right: 1px solid #eee; border-bottom: 1px solid #eee; } .operate-item { /*display: flex;*/ /*flex-direction: column;*/ /*justify-content: space-between;*/ height: 170px; } .table-container .operate-table .w1 { width: 100%; } .h1 { height: 100%; } .i1 { margin: 5px 0 5px 0; } .table-container .operate-table .icon { width: 20px; height: 20px; margin: 0 10px 0 0; }