Djcs3.js 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177
  1. import * as React from 'react';
  2. import Box from "@mui/material/Box";
  3. import Table from 'rsuite/Table';
  4. import 'rsuite/Table/styles/index.css';
  5. import Checkbox from 'rsuite/Checkbox';
  6. import 'rsuite/Checkbox/styles/index.css';
  7. import { CustomProvider, Input, InputNumber } from 'rsuite';
  8. import 'rsuite/InputNumber/styles/index.css';
  9. import zhCN from 'rsuite/locales/zh_CN';
  10. import Tab from "@mui/material/Tab";
  11. import TabContext from "@mui/lab/TabContext";
  12. import TabList from "@mui/lab/TabList";
  13. import TabPanel from "@mui/lab/TabPanel";
  14. import Stack from "@mui/material/Stack";
  15. import Radio from '@mui/material/Radio';
  16. import Typography from '@mui/material/Typography';
  17. import RadioGroup from '@mui/material/RadioGroup';
  18. import FormControlLabel from '@mui/material/FormControlLabel';
  19. import FormControl from '@mui/material/FormControl';
  20. import FormLabel from '@mui/material/FormLabel';
  21. import Service from './Service';
  22. import SimpleService from './SimpleService';
  23. import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
  24. import './Tabulator.css';
  25. import {extractFuzhu, match_target} from './utils';
  26. import Button from '@mui/material/Button';
  27. import {handleAI_djcs, shanchu_djcs, undo_djcs, redo_djcs, danxiangdinge_djcs, updateDercj_djcs, changguidinge_djcs, handleBeizhu_djcs, handleYuban_djcs, huan, updateShuliang_djcs, azfy_djcs_eligible, azfy_djcs} from './editor';
  28. import {copy} from './utils';
  29. import { useNavigate } from "react-router";
  30. const {Column, HeaderCell, Cell} = Table;
  31. function number_equal(a, b) {
  32. if (Number(a) - Number(b) < 0.0001 && Number(a) - Number(b) > -0.0001) {
  33. return true;
  34. }
  35. return false;
  36. }
  37. export default function Djcs3({name, bh, beizhu, beizhuFK, clickCallback, AICallback,AIClick, loadingCallback, dingeclick, azfycallback, azfySelect, azfyConfirm}) {
  38. const navigate = useNavigate();
  39. var editCheck = function(cell){
  40. //cell - the cell component for the editable cell
  41. //get row data
  42. //console.log(cell);
  43. if(cell._cell.row.data['序号']) return false;
  44. return true;
  45. }
  46. var editCheckRcj = function(cell){
  47. //cell - the cell component for the editable cell
  48. //get row data
  49. //console.log(cell);
  50. if(isQdrcj.current) return false;
  51. if (cell._cell.row.getData()['人材机编码'] == '00EXP001') {//回程费
  52. return false;
  53. }
  54. if (cell._cell.row.getData()['人材机编码'] == '99EXP007') {//
  55. return false;
  56. }
  57. if (cell._cell.row.getData()['人材机编码'] == '99EXP022') {//
  58. return false;
  59. }
  60. if (cell._cell.row.getData()['人材机编码'] == '31130104') {//
  61. return false;
  62. }
  63. if (cell._cell.row.getData()['人材机编码'].includes('000FE')) {//安装费用
  64. return false;
  65. }
  66. return true;
  67. }
  68. var editCheckJg = function(cell){
  69. //cell - the cell component for the editable cell
  70. //get row data
  71. //console.log(cell);
  72. if(isQdrcj.current) return false;
  73. if (cell._cell.row.getData()['人材机编码'] == '00EXP001') {//回程费
  74. return false;
  75. }
  76. if (cell._cell.row.getData()['人材机编码'] == '99EXP007') {//
  77. return false;
  78. }
  79. if (cell._cell.row.getData()['人材机编码'] == '99EXP022') {//
  80. return false;
  81. }
  82. if (cell._cell.row.getData()['人材机编码'] == '31130104') {//
  83. return false;
  84. }
  85. if (cell._cell.row.getData()['甲供标志'] == 'true') {//
  86. return false;
  87. }
  88. if (cell._cell.row.getData()['人材机编码'].includes('000FE')) {//安装费用
  89. return false;
  90. }
  91. return true;
  92. }
  93. var sparklineFormatter = function(cell, formatterParams, onRendered){
  94. for (let i = 0; i < highlight.current.length; i++) {
  95. let entry = highlight.current[i];
  96. if (entry.row + 1 == cell._cell.row.position && entry.col + 1 == cell._cell.column.getPosition()) {
  97. cell.getElement().style.fontWeight = 'bold';
  98. cell.getElement().style.color = 'green';
  99. cell.getElement().style.background = '#d7f1e1';
  100. }
  101. }
  102. return Number(cell.getValue()).toFixed(2).toString();
  103. };
  104. var sparklineFormatter2 = function(cell, formatterParams, onRendered){
  105. for (let i = 0; i < highlight.current.length; i++) {
  106. let entry = highlight.current[i];
  107. if (entry.row + 1 == cell._cell.row.position && entry.col + 1 == cell._cell.column.getPosition()) {
  108. cell.getElement().style.fontWeight = 'bold';
  109. cell.getElement().style.color = 'green';
  110. cell.getElement().style.background = '#d7f1e1';
  111. }
  112. }
  113. return cell.getValue();
  114. };
  115. function handleSelect(row){
  116. //e - the click event object
  117. //cell - cell component
  118. console.log('rowSelected');
  119. selectedRowKeysTable.current = [row._row['data']['key']];
  120. let bt = "Djcs" ;
  121. if (row._row.data['序号'] != null && row._row.data['序号'].length >0) {
  122. selectedRowKeysTableParent.current = row._row['data']['key'];
  123. setFuzhu([]);
  124. setYubanEnable(false);
  125. setValueYuban("");
  126. Service.generateQingdanrcj(name, bh,bt,row._row.data['清单编码']).then(x=>{
  127. let y =[];
  128. for (let i = 1; i < x.length; i++) {
  129. y.push({
  130. 'ID' : x[i][0],
  131. '人材机编码' : x[i][1],
  132. '名称' : x[i][2],
  133. '规格型号': x[i][3],
  134. '单位' : x[i][4],
  135. '单价' : x[i][5],
  136. '产地' : x[i][6],
  137. '供应厂商' : x[i][7],
  138. '人材机类别' : x[i][8],
  139. '甲供标志': x[i][9],
  140. '含量' : x[i][10],
  141. '合价' : x[i][11],
  142. '暂估价标志' : x[i][12],
  143. '主要材料标志' : x[i][13],
  144. '主材标志' : x[i][14],
  145. '设备标志' : x[i][15] ,
  146. 'key' : '',
  147. 'bc': ''
  148. });
  149. }
  150. setRcjhl(y);
  151. if (rcjTable.current) {
  152. rcjTable.current.replaceData(y);
  153. }
  154. isQdrcj.current=true;
  155. highlight.current = [];
  156. });
  157. SimpleService.generateQingdanTuijian(name, bh,bt,row._row.data['清单编码']).then(x=>{
  158. setTuijian(x);
  159. if (tuijianTable.current) tuijianTable.current.replaceData(x);
  160. });
  161. } else {
  162. setTuijian([]);
  163. if (tuijianTable.current) tuijianTable.current.replaceData([]);
  164. let row_parent = row._row;
  165. while(row_parent.modules.dataTree.parent) {
  166. row_parent = row_parent.modules.dataTree.parent;
  167. }
  168. debmRef.current = row._row['data']['清单编码'];
  169. selectedRowKeysTableParent.current = row_parent['data']['key'];
  170. clickCallback('Djcs', row_parent['data']['清单编码'], row._row['data']['清单编码'], row._row['data']['名称']);
  171. Service.generateDingercj(name, bh,bt,row_parent['data']['清单编码'], row._row['data']['清单编码'], row._row['data']['单位'], row._row['data']['key']).then(x=>{
  172. let y =[];
  173. for (let i = 1; i < x[0].length; i++) {
  174. y.push({
  175. 'ID' : x[0][i][0],
  176. '人材机编码' : x[0][i][1],
  177. '名称' : x[0][i][2],
  178. '规格型号': x[0][i][3],
  179. '单位' : x[0][i][4],
  180. '单价' : x[0][i][5],
  181. '产地' : x[0][i][6],
  182. '供应厂商' : x[0][i][7],
  183. '人材机类别' : x[0][i][8],
  184. '甲供标志': x[0][i][9],
  185. '含量' : x[0][i][10],
  186. '合价' : x[0][i][11],
  187. '暂估价标志' : x[0][i][12],
  188. '主要材料标志' : x[0][i][13],
  189. '主材标志' : x[0][i][14],
  190. '设备标志' : x[0][i][15] ,
  191. 'key' : x[0][i][16],
  192. 'bc': x[0][i][17]
  193. });
  194. }
  195. setRcjhl(y);
  196. if (rcjTable.current) {
  197. rcjTable.current.replaceData(y);
  198. }
  199. isQdrcj.current = false;
  200. setFuzhuEnable(x[1]);
  201. setYubanEnable(x[1]);
  202. if (x[2]== null || x[2].length == 0) {
  203. setValueYuban("");
  204. } else {
  205. setValueYuban(x[2][0]);
  206. }
  207. let toHighlight = [];
  208. highlight.current = toHighlight;
  209. });
  210. }
  211. }
  212. const [detail, setDetail] = React.useState([
  213. ]);
  214. const myRef = React.useRef(null);
  215. const myTable = React.useRef(null);
  216. const tuijianRef = React.useRef(null);
  217. const tuijianTable = React.useRef(null);
  218. const rcj2Ref = React.useRef(null);
  219. const rcj2Table = React.useRef(null);
  220. const rcjRef = React.useRef(null);
  221. const rcjTable = React.useRef(null);
  222. const [value, setValue] = React.useState("1");
  223. const [rcjhl, setRcjhl] = React.useState([]);
  224. const [rcjhl2, setRcjhl2] = React.useState([]);
  225. const [fuzhu, setFuzhu] = React.useState([]);
  226. const [tuijian, setTuijian] = React.useState([]);
  227. const beizhuFKRef = React.useRef(null);
  228. const [fuzhuEnable, setFuzhuEnable] = React.useState(false);
  229. const [yubanEnable, setYubanEnable] = React.useState(false);
  230. const [valueYuban, setValueYuban] = React.useState("");
  231. //预拌砂浆
  232. const onSelectChange2 = (event) => {
  233. setValueYuban(event.target.value);
  234. const [newData, newHl] = handleYuban_djcs(selectedRowKeysTable.current[0], [event.target.value]);
  235. if (newData) {
  236. let former = myTable.current.element.children[1].scrollTop;
  237. let former2 = myTable.current.element.children[1].scrollLeft;
  238. myTable.current.deselectRow();
  239. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  240. myTable.current.element.children[1].scrollTop = former;
  241. myTable.current.element.children[1].scrollLeft = former2;
  242. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  243. let component = null;
  244. for(let i = 0; i < getRow.length; i++) {
  245. let entry = getRow[i]._row.modules.dataTree.children;
  246. for(let j = 0; j < entry.length; j++) {
  247. let child = entry[j];
  248. if(child.data['key'] == selectedRowKeysTable.current[0]) {
  249. component = child.component;
  250. break;
  251. }
  252. }
  253. }
  254. component.select();
  255. });
  256. let y =[];
  257. for (let i = 1; i < newHl.length; i++) {
  258. y.push({
  259. 'ID' : newHl[i][0],
  260. '人材机编码' : newHl[i][1],
  261. '名称' : newHl[i][2],
  262. '规格型号': newHl[i][3],
  263. '单位' : newHl[i][4],
  264. '单价' : newHl[i][5],
  265. '产地' : newHl[i][6],
  266. '供应厂商' : newHl[i][7],
  267. '人材机类别' : newHl[i][8],
  268. '甲供标志': newHl[i][9],
  269. '含量' : newHl[i][10],
  270. '合价' : newHl[i][11],
  271. '暂估价标志' : newHl[i][12],
  272. '主要材料标志' : newHl[i][13],
  273. '主材标志' : newHl[i][14],
  274. '设备标志' : newHl[i][15] ,
  275. 'key' : newHl[i][16],
  276. 'bc': newHl[i][17]
  277. });
  278. }
  279. setRcjhl(y);
  280. if (rcjTable.current) {
  281. rcjTable.current.replaceData(y);
  282. }
  283. }
  284. };
  285. const onSelectChange = (newSelectedRowKeys) => {
  286. const [newData, newHl] = handleBeizhu_djcs(beizhuFKRef.current, selectedRowKeysTable.current[0], newSelectedRowKeys, fuzhu);
  287. if (newData) {
  288. let former = myTable.current.element.children[1].scrollTop;
  289. let former2 = myTable.current.element.children[1].scrollLeft;
  290. myTable.current.deselectRow();
  291. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  292. myTable.current.element.children[1].scrollTop = former;
  293. myTable.current.element.children[1].scrollLeft = former2;
  294. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  295. let component = null;
  296. for(let i = 0; i < getRow.length; i++) {
  297. let entry = getRow[i]._row.modules.dataTree.children;
  298. for(let j = 0; j < entry.length; j++) {
  299. let child = entry[j];
  300. if(child.data['key'] == selectedRowKeysTable.current[0]) {
  301. component = child.component;
  302. break;
  303. }
  304. }
  305. }
  306. component.select();
  307. });
  308. let y =[];
  309. for (let i = 1; i < newHl.length; i++) {
  310. y.push({
  311. 'ID' : newHl[i][0],
  312. '人材机编码' : newHl[i][1],
  313. '名称' : newHl[i][2],
  314. '规格型号': newHl[i][3],
  315. '单位' : newHl[i][4],
  316. '单价' : newHl[i][5],
  317. '产地' : newHl[i][6],
  318. '供应厂商' : newHl[i][7],
  319. '人材机类别' : newHl[i][8],
  320. '甲供标志': newHl[i][9],
  321. '含量' : newHl[i][10],
  322. '合价' : newHl[i][11],
  323. '暂估价标志' : newHl[i][12],
  324. '主要材料标志' : newHl[i][13],
  325. '主材标志' : newHl[i][14],
  326. '设备标志' : newHl[i][15],
  327. 'key': newHl[i][16],
  328. 'bc': newHl[i][17]
  329. });
  330. }
  331. setRcjhl(y);
  332. if (rcjTable.current) {
  333. rcjTable.current.replaceData(y);
  334. }
  335. }
  336. };
  337. const highlight = React.useRef([]);
  338. //const [azfyDe, setAzfyDe] = React.useState(null);
  339. const rgdeRef = React.useRef(null);
  340. const jxdeRef = React.useRef(null);
  341. const cldeRef = React.useRef(null);
  342. const isQdrcj = React.useRef(false);
  343. const debmRef = React.useRef(null);
  344. const selectedRowKeysTable = React.useRef([]);
  345. const selectedRowKeysTableParent = React.useRef(null);
  346. ////beizhu table
  347. const [checked, setChecked] = React.useState(false);
  348. const [indeterminate, setIndeterminate] = React.useState(false);
  349. const [checkedKeys, setCheckedKeys] = React.useState([]);
  350. const setCheckedKeys_ = (keys) => {
  351. setCheckedKeys(keys);
  352. if (keys.length == fuzhu.length) {
  353. setChecked(true);
  354. setIndeterminate(false);
  355. } else if (keys.length == 0) {
  356. setChecked(false);
  357. setIndeterminate(false);
  358. } else {
  359. setIndeterminate(true);
  360. setChecked(false);
  361. }
  362. onSelectChange(keys);
  363. };
  364. /*initialization*/
  365. const setCheckedKeys_2 = (keys) => {
  366. setCheckedKeys(keys);
  367. if (keys.length == fuzhu.length) {
  368. setChecked(true);
  369. setIndeterminate(false);
  370. } else if (keys.length == 0) {
  371. setChecked(false);
  372. setIndeterminate(false);
  373. } else {
  374. setIndeterminate(true);
  375. setChecked(false);
  376. }
  377. };
  378. const handleCheckAll = (value, checked) => {
  379. const keys = checked? fuzhu.map(item => item.id) : [];
  380. setCheckedKeys_(keys);
  381. }
  382. const handleCheck = (value, checked) => {
  383. const keys = checked? [...checkedKeys, value] : checkedKeys.filter(item => item != value);
  384. setCheckedKeys_(keys);
  385. }
  386. const CheckCell = ({rowData, onChange, checkedKeys, dataKey, disabled, ...props}) => {
  387. return <Cell {...props} style={{ padding: 0}}>
  388. <div style={{lineHeight: '40px'}}>
  389. <Checkbox value = {rowData[dataKey]}
  390. inline
  391. disabled={disabled}
  392. onChange={onChange}
  393. checked={checkedKeys.some(item => item === rowData[dataKey])}
  394. ></Checkbox>
  395. </div>
  396. </Cell>
  397. };
  398. const resetUI = () => {
  399. selectedRowKeysTable.current = [];
  400. selectedRowKeysTableParent.current = null;
  401. setRcjhl([]);
  402. if (rcjTable.current) {
  403. rcjTable.current.replaceData([]);
  404. }
  405. setFuzhu([]);
  406. setYubanEnable(false);
  407. setValueYuban("");
  408. isQdrcj.current = true;
  409. highlight.current = [];
  410. setTuijian([]);
  411. if (tuijianTable.current) tuijianTable.current.replaceData([]);
  412. };
  413. React.useEffect(() => {
  414. myTable.current = new Tabulator(myRef.current, {
  415. index: "key",
  416. height: 480,//adjust
  417. renderVertical: "basic",
  418. data: detail, //link data to table
  419. reactiveData: false, //enable data reactivity
  420. dataTreeStartExpanded:true,
  421. dataTree: true,
  422. selectableRows:1, //make rows selectable
  423. editTriggerEvent:"dblclick", //trigger edit on double click
  424. dataTreeStartExpanded:function(row, level){
  425. return true;
  426. },
  427. columns: [ //Define Table Columns
  428. {title:"序号", field:"序号", width:80, headerSort:false, frozen: true}, //never hide this column
  429. {title:"清单编码", field:"清单编码", width:120,headerSort:false, frozen: true, formatter:"textarea" },
  430. {title:"名称", field:"名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
  431. {title:"项目特征", field:"项目特征", width:150 , headerSort:false, formatter:"textarea"},
  432. {title:"计算规则", field:"计算规则", width:250, headerSort:false, formatter:"textarea"},
  433. {title:"单位", field:"单位", width:100, headerSort:false},
  434. {title:"数量", field:"数量", width:100, headerSort:false, editor: "input", editable: editCheck },
  435. {title:"综合单价", field:"综合单价", width:100, headerSort:false, formatter:"money"},
  436. {title:"合价", field:"合价", width:100, headerSort:false, formatter:"money"},
  437. {title:"人工费", field:"人工费", width:100, headerSort:false, formatter:"money"},
  438. {title:"主材费", field:"主材费", width:100, headerSort:false, formatter:"money"},
  439. {title:"设备费", field:"设备费", width:100, headerSort:false, formatter:"money"},
  440. {title:"辅材费", field:"辅材费", width:100, headerSort:false, formatter:"money"},
  441. {title:"材料费", field:"材料费", width:100, headerSort:false, formatter:"money"},
  442. {title:"机械费", field:"机械费", width:100, headerSort:false, formatter:"money"},
  443. {title:"管理费", field:"管理费", width:100, headerSort:false, formatter:"money"},
  444. {title:"利润", field:"利润", width:100, headerSort:false, formatter:"money"},
  445. {title:"暂估价", field:"暂估价", width:100, headerSort:false, formatter:"money"},
  446. {title:"综合人工工日", field:"综合人工工日", width:100, headerSort:false},
  447. ]
  448. });
  449. myTable.current.on("cellDblClick", function(e, cell){
  450. //e - the click event object
  451. //cell - cell component
  452. console.log(cell);
  453. });
  454. myTable.current.on("rowSelected", handleSelect);
  455. myTable.current.on("cellEdited", function(cell){
  456. //console.log("edited");
  457. //console.log();
  458. let key = cell._cell.row.data['key'];
  459. myTable.current.deselectRow();
  460. let [success, data] = updateShuliang_djcs(cell._cell.row.data['数量'], selectedRowKeysTable.current[0]);
  461. if (success) {
  462. let former = myTable.current.element.children[1].scrollTop;
  463. let former2 = myTable.current.element.children[1].scrollLeft;
  464. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function() {
  465. myTable.current.element.children[1].scrollTop = former;
  466. myTable.current.element.children[1].scrollLeft = former2;
  467. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  468. let component = null;
  469. for(let i = 0; i < getRow.length; i++) {
  470. let entry = getRow[i]._row.modules.dataTree.children;
  471. for(let j = 0; j < entry.length; j++) {
  472. let child = entry[j];
  473. if(child.data['key'] == key) {
  474. //console.log(child);
  475. component = child.component;
  476. break;
  477. }
  478. }
  479. }
  480. component.select();
  481. //handleSelect(component);
  482. });
  483. }
  484. });
  485. myTable.current.on("tableBuilt", () => {
  486. Service.generateDjcs(name, bh, navigate).then(x=>{
  487. myTable.current.replaceData(x);
  488. });
  489. });
  490. }, [bh]);
  491. React.useEffect(
  492. () => {
  493. if (AIClick!=null){
  494. console.log(AIClick);
  495. const [success, data, key] = handleAI_djcs(AIClick);
  496. if(success) {
  497. let former = myTable.current.element.children[1].scrollTop;
  498. let former2 = myTable.current.element.children[1].scrollLeft;
  499. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  500. myTable.current.element.children[1].scrollTop = former;
  501. myTable.current.element.children[1].scrollLeft = former2;
  502. resetUI();
  503. });
  504. }
  505. }
  506. }, [AIClick]//AI添加定额
  507. );
  508. React.useEffect(
  509. () => {
  510. beizhuFKRef.current = beizhuFK;
  511. }, [beizhuFK]
  512. );
  513. React.useEffect(
  514. () => {
  515. //console.log(dingeclick);
  516. //console.log(azfySelect);
  517. if (dingeclick != null && selectedRowKeysTable.current != null && azfy_djcs_eligible(selectedRowKeysTable.current[0])) {
  518. const [success, data, key] = azfy_djcs(selectedRowKeysTable.current[0], dingeclick, azfySelect);
  519. myTable.current.deselectRow();
  520. let former = myTable.current.element.children[1].scrollTop;
  521. let former2 = myTable.current.element.children[1].scrollLeft;
  522. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  523. myTable.current.element.children[1].scrollTop = former;
  524. myTable.current.element.children[1].scrollLeft = former2;
  525. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  526. let component = null;
  527. for(let i = 0; i < getRow.length; i++) {
  528. let entry = getRow[i]._row.modules.dataTree.children;
  529. for(let j = 0; j < entry.length; j++) {
  530. let child = entry[j];
  531. if(child.data['key'] == key) {
  532. //console.log(child);
  533. component = child.component;
  534. break;
  535. }
  536. }
  537. }
  538. component.select();
  539. //handleSelect(component);
  540. });
  541. }
  542. }, [azfyConfirm]
  543. );
  544. React.useEffect(
  545. () => {
  546. //console.log(beizhu);
  547. let result = [];
  548. if (beizhu != null) {
  549. let keys = Object.keys(beizhu["BZBH"]);
  550. for(let i = 0; i < keys.length; i++) {
  551. let key = keys[i];
  552. result.push({'id': i+1, 'key': i+1, '序号': i+1, '编号': beizhu["BZBH"][key], '说明': beizhu["SM"][key], '数量': 1});//序号很重要
  553. }
  554. let newSelect = extractFuzhu(debmRef.current);
  555. setCheckedKeys_2(newSelect.map(x=>x.split("*")[0]).map(x=>Number(x)));
  556. for(let i = 0; i < newSelect.length; i++) {
  557. if (newSelect[i].includes('*')) {
  558. let xuhao = Number(newSelect[i].split('*')[0]);
  559. let coef = Number(newSelect[i].split('*')[1]);
  560. for(let j = 0; j < result.length; j++) {
  561. if (result[j]['id'] == xuhao) {
  562. result[j]['数量'] = coef;
  563. }
  564. }
  565. }
  566. }
  567. setFuzhu(result);
  568. }
  569. }, [beizhu]
  570. );
  571. React.useEffect(
  572. () => {
  573. if (tuijianRef.current != null ) {
  574. tuijianTable.current = new Tabulator(tuijianRef.current, {
  575. index: "key",
  576. height: 240,
  577. data: tuijian, //link data to table
  578. reactiveData: false, //enable data reactivity
  579. dataTreeStartExpanded:false,
  580. dataTree: false,
  581. selectableRows:1, //make rows selectable
  582. columns: [ //Define Table Columns
  583. {title:"ID", field:"ID", width:80, headerSort:false, }, //never hide this column
  584. {title:"定额编号", field:"定额编号", width:120,headerSort:false, formatter:"textarea" },
  585. {title:"工程量名称", field:"工程量名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
  586. {title:"工作内容", field:"工作内容", width:150 , headerSort:false, formatter:"textarea"},
  587. ]
  588. });
  589. tuijianTable.current.on("tableBuilt", () => {
  590. tuijianTable.current.replaceData(tuijian);
  591. });
  592. }
  593. if (rcj2Ref.current != null ) {
  594. rcj2Table.current = new Tabulator(rcj2Ref.current, {
  595. index: "key",
  596. height: 240,
  597. data: rcjhl2, //link data to table
  598. reactiveData: false, //enable data reactivity
  599. dataTreeStartExpanded:false,
  600. dataTree: false,
  601. selectableRows:1, //make rows selectable
  602. columns: [ //Define Table Columns
  603. {title:"人材机编码", field:"人材机编码", width:120, headerSort:false, }, //never hide this column
  604. {title:"名称", field:"名称", width:120,headerSort:false, formatter:"textarea" },
  605. {title:"单位", field:"单位", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
  606. {title:"单价", field:"单价", width:150 , headerSort:false, formatter:"money"},
  607. {title:"合价", field:"合价", width:150 , headerSort:false, formatter:"money"},
  608. {title:"含量", field:"含量", width:150 , headerSort:false, formatter:"textarea"},
  609. ]
  610. });
  611. rcj2Table.current.on("tableBuilt", () => {
  612. rcj2Table.current.replaceData(rcjhl2);
  613. });
  614. }
  615. if (rcjRef.current != null ) {
  616. rcjTable.current = new Tabulator(rcjRef.current, {
  617. index: "key",
  618. height: 240,
  619. data: rcjhl, //link data to table
  620. reactiveData: false, //enable data reactivity
  621. dataTreeStartExpanded:false,
  622. dataTree: false,
  623. selectableRows:1, //make rows selectable
  624. editTriggerEvent:"dblclick",
  625. renderVertical: "basic",
  626. columns: [ //Define Table Columns
  627. {title:"ID", field:"ID", width:80, headerSort:false, },
  628. {title:"人材机编码", field:"人材机编码", width:120, headerSort:false, formatter: sparklineFormatter2}, //never hide this column
  629. {title:"名称", field:"名称", width:120,headerSort:false, formatter:"textarea", editor: "input", editable: editCheckRcj },
  630. {title:"规格型号", field:"规格型号", width:80, headerSort:false, editor: "input", editable: editCheckRcj },
  631. {title:"单位", field:"单位", width:80, headerSort:false, formatter:"textarea"}, //hide this column first
  632. {title:"单价", field:"单价", width:80 , headerSort:false, formatter: sparklineFormatter, editor: "input", editable: editCheckJg },
  633. {title:"产地", field:"产地", width:80, headerSort:false, },
  634. {title:"供应厂商", field:"供应厂商", width:80, headerSort:false, },
  635. {title:"人材机类别", field:"人材机类别", width:120, headerSort:false, },
  636. {title:"甲供标志", field:"甲供标志", width:80 , headerSort:false, formatter:"textarea"},
  637. {title:"含量", field:"含量", width:120 , headerSort:false, formatter:"money", formatterParams:{precision:4}, editor: "input", editable: editCheckRcj },
  638. {title:"合价", field:"合价", width:80 , headerSort:false, formatter:"money"},
  639. {title:"暂估价标志", field:"暂估价标志", width:100 , headerSort:false, formatter:"textarea"},
  640. {title:"主要材料标志", field:"主要材料标志", width:100 , headerSort:false, formatter:"textarea"},
  641. {title:"主材标志", field:"主材标志", width:80 , headerSort:false, formatter:"textarea"},
  642. {title:"设备标志", field:"设备标志", width:80 , headerSort:false, formatter:"textarea"},
  643. ]
  644. });
  645. rcjTable.current.on("tableBuilt", () => {
  646. rcjTable.current.replaceData(rcjhl);
  647. });
  648. rcjTable.current.on("cellEdited", function(cell){
  649. let data = copy(cell._cell.table.getData());
  650. for(let i = 0; i < data.length; i++) {
  651. data[i]['合价'] = Number(data[i]['单价']) * Number(data[i]['含量']);
  652. }
  653. setRcjhl(data);
  654. if (rcjTable.current) {
  655. rcjTable.current.replaceData(data);
  656. }
  657. let data2 = [['ID', '人材机编码', '名称', '规格型号', '单位', '单价', '产地', '供应厂商', '人材机类别', '甲供标志', '含量', '合价', '暂估价标志', '主要材料标志', '主材标志', '设备标志', "key", "bc"]]
  658. for (let i = 0; i < data.length; i++) {
  659. data2.push([data[i]['ID'], data[i]['人材机编码'], data[i]['名称'], data[i]['规格型号'], data[i]['单位'],
  660. data[i]['单价'], data[i]['产地'], data[i]['供应厂商'], data[i]['人材机类别'],
  661. data[i]['甲供标志'], data[i]['含量'], data[i]['合价'], data[i]['暂估价标志'], data[i]['主要材料标志'], data[i]['主材标志'], data[i]['设备标志'], data[i]['key'], data[i]['bc']]);
  662. }
  663. let newData = updateDercj_djcs(selectedRowKeysTable.current[0], data2);
  664. myTable.current.deselectRow();
  665. let former = myTable.current.element.children[1].scrollTop;
  666. let former2 = myTable.current.element.children[1].scrollLeft;
  667. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function() {
  668. myTable.current.element.children[1].scrollTop = former;
  669. myTable.current.element.children[1].scrollLeft = former2;
  670. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  671. let component = null;
  672. for(let i = 0; i < getRow.length; i++) {
  673. let entry = getRow[i]._row.modules.dataTree.children;
  674. for(let j = 0; j < entry.length; j++) {
  675. let child = entry[j];
  676. if(child.data['key'] == selectedRowKeysTable.current[0]) {
  677. //console.log(child);
  678. component = child.component;
  679. break;
  680. }
  681. }
  682. }
  683. component.select();
  684. //handleSelect(component);
  685. });
  686. });
  687. }
  688. }, [value]
  689. );
  690. React.useEffect(
  691. () => {
  692. let input = JSON.parse(dingeclick);
  693. if (input == null) {
  694. return;
  695. }
  696. if (!input.hasOwnProperty("DEBH")) {
  697. return;
  698. }
  699. let bh_ = Object.values(input['DEBH'])[0];
  700. if (bh_.includes('-F') || bh_.includes('19-19') || bh_.includes('19-20') || bh_.includes('19-21') || bh_.includes('19-22') || bh_.includes('19-23') || bh_.includes('19-24') || bh_.includes('19-25') || bh_.includes('19-26') || bh_.includes('19-27') || bh_.includes('19-28') || bh_.includes('19-29') || bh_.includes('19-30') || bh_.includes('19-31') || bh_.includes('19-32') || bh_.includes('19-33') || bh_.includes('19-34') || bh_.includes('19-35') || bh_.includes('19-36')) {
  701. if (selectedRowKeysTable.current.length > 0 ) {
  702. if (azfy_djcs_eligible(selectedRowKeysTable.current[0])) {
  703. //setAzfyDe(input);
  704. azfycallback(bh, input);
  705. }
  706. }
  707. } else {
  708. myTable.current.deselectRow();
  709. //console.log(dingeclick);
  710. if (selectedRowKeysTable.current.length > 0 ) {
  711. const [success, data, key] = changguidinge_djcs(input, selectedRowKeysTable.current[0]);
  712. if (success) {
  713. let former = myTable.current.element.children[1].scrollTop;
  714. let former2 = myTable.current.element.children[1].scrollLeft;
  715. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  716. myTable.current.element.children[1].scrollTop = former;
  717. myTable.current.element.children[1].scrollLeft = former2;
  718. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  719. let component = null;
  720. for(let i = 0; i < getRow.length; i++) {
  721. let entry = getRow[i]._row.modules.dataTree.children;
  722. for(let j = 0; j < entry.length; j++) {
  723. let child = entry[j];
  724. if(child.data['key'] == key) {
  725. //console.log(child);
  726. component = child.component;
  727. break;
  728. }
  729. }
  730. }
  731. component.select();
  732. //handleSelect(component);
  733. });
  734. }
  735. }
  736. }
  737. }, [dingeclick]//常规添加定额
  738. );
  739. const handleChange = (event, newValue) => {
  740. setValue(newValue);
  741. };
  742. const EditableContext = React.createContext({ editingId: null, editingKey: null });
  743. const [editingId, setEditingId] = React.useState(null);
  744. const [editingKey, setEditingKey] = React.useState(null);
  745. const onEdit = (id, dataKey) => {
  746. setEditingId(id);
  747. setEditingKey(dataKey);
  748. };
  749. const onEditFinished = () => {
  750. //console.log("edit finidhed");
  751. setEditingId(null);
  752. setEditingKey(null);
  753. onSelectChange(checkedKeys);
  754. };
  755. const styles = `
  756. .table-cell-editing .rs-table-cell-content {
  757. padding: 4px;
  758. }
  759. .table-cell-editing .rs-input {
  760. width: 100%;
  761. }
  762. .table-cell:focus {
  763. outline: none;
  764. box-shadow: inset 0 0 0 1px #007bff;
  765. }
  766. `;
  767. const fieldMap = {
  768. string: Input,
  769. number: InputNumber,
  770. };
  771. function focus(ref) {
  772. setTimeout(() => {
  773. if (ref.current?.tagName === 'INPUT' || ref.current?.getAttribute('tabindex') === '0') {
  774. ref.current.focus();
  775. } else if (ref.current instanceof HTMLElement) {
  776. ref.current.querySelector('input').focus();
  777. }
  778. }, 10);
  779. }
  780. const handleChangeFuzhuSL = (id, key, value) => {
  781. const nextData = Object.assign([], fuzhu);
  782. nextData.find(item => item.id === id)[key] = value;
  783. setFuzhu(nextData);
  784. };
  785. const EditableCell = ({ rowData, dataType, dataKey, onChange, ...props }) => {
  786. const { editingId, editingKey, onEdit, onEditFinished } = React.useContext(EditableContext);
  787. const editing = rowData.id === editingId && dataKey === editingKey;
  788. const Field = fieldMap[dataType];
  789. const value = rowData[dataKey];
  790. const text = value;
  791. const inputRef = React.useRef();
  792. const cellRef = React.useRef();
  793. const handleEdit = () => {
  794. if (fuzhuEnable) {
  795. onEdit?.(rowData.id, dataKey);
  796. focus(inputRef);
  797. }
  798. };
  799. const handleFinished = () => {
  800. onEditFinished();
  801. focus(cellRef);
  802. };
  803. return (
  804. <Cell
  805. {...props}
  806. ref={cellRef}
  807. tabIndex={0}
  808. className={editing ? 'table-cell-editing' : 'table-cell'}
  809. onDoubleClick={handleEdit}
  810. >
  811. {editing ? (
  812. <Field
  813. ref={inputRef}
  814. defaultValue={value}
  815. onBlur={handleFinished}
  816. onKeyPress={e => {
  817. if (e.key === 'Enter') {
  818. handleFinished();
  819. }
  820. }}
  821. onChange={value => {
  822. onChange?.(rowData.id, dataKey, value);
  823. }}
  824. />
  825. ) : (
  826. text
  827. )}
  828. </Cell>
  829. );
  830. };
  831. return (
  832. <Stack spacing={1}>
  833. <Stack direction='row' spacing={2}>
  834. <Button variant="outlined" size="small" onClick={() => {
  835. if (selectedRowKeysTable.current.length > 0) {
  836. const [success, data] = danxiangdinge_djcs(selectedRowKeysTable.current[0]);
  837. if(success) {
  838. let former = myTable.current.element.children[1].scrollTop;
  839. let former2 = myTable.current.element.children[1].scrollLeft;
  840. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  841. myTable.current.element.children[1].scrollTop = former;
  842. myTable.current.element.children[1].scrollLeft = former2;
  843. resetUI();
  844. });
  845. }
  846. }
  847. }}
  848. >单项定额</Button>
  849. <Button variant="outlined" size="small" onClick={() => {
  850. if (selectedRowKeysTable.current.length > 0) {
  851. let newData = shanchu_djcs(selectedRowKeysTable.current[0]);
  852. let former = myTable.current.element.children[1].scrollTop;
  853. let former2 = myTable.current.element.children[1].scrollLeft;
  854. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  855. myTable.current.element.children[1].scrollTop = former;
  856. myTable.current.element.children[1].scrollLeft = former2;
  857. // if (newData.filter(x=>x['key'] == selectedRowKeysTable.current[0]).length == 0) {
  858. resetUI();
  859. // }
  860. });
  861. }
  862. }}
  863. >删除</Button>
  864. <Button variant="outlined" size="small" onClick={() => {
  865. let newData = undo_djcs();
  866. let former = myTable.current.element.children[1].scrollTop;
  867. let former2 = myTable.current.element.children[1].scrollLeft;
  868. myTable.current.updateData(newData).then(function(){
  869. myTable.current.element.children[1].scrollTop = former;
  870. myTable.current.element.children[1].scrollLeft = former2;
  871. resetUI();
  872. });
  873. }}
  874. >撤销</Button>
  875. <Button variant="outlined" size="small" onClick={() => {
  876. let newData = redo_djcs();
  877. let former = myTable.current.element.children[1].scrollTop;
  878. let former2 = myTable.current.element.children[1].scrollLeft;
  879. myTable.current.updateData(newData).then(function(){
  880. myTable.current.element.children[1].scrollTop = former;
  881. myTable.current.element.children[1].scrollLeft = former2;
  882. resetUI();
  883. });
  884. }}
  885. >重做</Button>
  886. <Button variant="outlined" size="small" onClick={() => {
  887. console.log("save to cloud");
  888. loadingCallback();
  889. }}
  890. >保存</Button>
  891. <Button variant="outlined" size="small" onClick={() => {
  892. console.log("AI");
  893. console.log(selectedRowKeysTableParent.current);
  894. let target = myTable.current.getRows().filter(x=>x._row['data']['key']==selectedRowKeysTableParent.current);
  895. if (target.length > 0){
  896. let rows = myTable.current.getRows();
  897. let maxN = 0;
  898. for(let i = 0; i < rows.length; i++) {
  899. let r = rows[i];
  900. let c = (r._row['data']['_children']);
  901. for (let j = 0; j < c.length; j++) {
  902. let bm = c[j]['清单编码'];
  903. if (bm.startsWith("D")){
  904. let bm2 = bm.substring(1);
  905. let n = parseInt(bm2, 10);
  906. if (n > maxN) {
  907. maxN = n;
  908. }
  909. }
  910. }
  911. }
  912. AICallback(target[0]._row['data'], maxN);
  913. }
  914. }}
  915. >小造AI</Button>
  916. </Stack>
  917. <div ref={myRef}>
  918. </div>
  919. <Box >
  920. <TabContext value={value}>
  921. <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
  922. <TabList onChange={handleChange} aria-label="lab API tabs example" sx={{minHeight: '24px'}} >
  923. <Tab sx={{p: 0, minHeight: '24px'}} label="人材机含量" value="1" />
  924. <Tab sx={{p: 0, minHeight: '24px'}} label="定额附注" value="3" />
  925. <Tab sx={{p: 0, minHeight: '24px'}} label="预拌砂浆" value="5" />
  926. <Tab sx={{p: 0, minHeight: '24px'}} label="组价推荐" value="4" />
  927. </TabList>
  928. </Box>
  929. <TabPanel value="1">
  930. <div ref={rcjRef}></div>
  931. </TabPanel>
  932. <TabPanel value="2">
  933. <div ref={rcj2Ref}></div>
  934. </TabPanel>
  935. <TabPanel value="3">
  936. <Box sx={{maxHeight: `240px`, minHeight: `240px`, height: `240px`}}>
  937. <CustomProvider locale={zhCN}>
  938. <EditableContext.Provider value={{ editingId, editingKey, onEdit, onEditFinished }}>
  939. <style>{styles}</style>
  940. <Table rowHeight={rowData=>{
  941. return 40;
  942. }}
  943. height={240} data = {fuzhu} id="fuzhu">
  944. <Column width={80} align="center">
  945. <HeaderCell style={{padding: 0}}>
  946. <div style={{lineHeight: '40px'}}>
  947. <Checkbox inline checked={checked} indeterminate={indeterminate} onChange={handleCheckAll} disabled={!fuzhuEnable}
  948. ></Checkbox>
  949. </div>
  950. </HeaderCell>
  951. <CheckCell dataKey="id" checkedKeys={checkedKeys} onChange={handleCheck} disabled={!fuzhuEnable}></CheckCell>
  952. </Column>
  953. <Column width={80} align="center">
  954. <HeaderCell style={{ "fontSize": "0.875rem" }}>序号</HeaderCell>
  955. <Cell dataKey="序号" style={{ "fontSize": "0.875rem" }}></Cell>
  956. </Column>
  957. <Column width={120} align="center">
  958. <HeaderCell style={{ "fontSize": "0.875rem" }}>编号</HeaderCell>
  959. <Cell dataKey="编号" style={{ "fontSize": "0.875rem" }}></Cell>
  960. </Column>
  961. <Column width={120} align="center">
  962. <HeaderCell style={{ "fontSize": "0.875rem" }}>数量</HeaderCell>
  963. <EditableCell dataKey="数量" dataType="number" style={{ "fontSize": "0.875rem" }} onChange={handleChangeFuzhuSL} />
  964. </Column>
  965. <Column fullText width={650} align="center">
  966. <HeaderCell style={{ "fontSize": "0.875rem" }}>说明</HeaderCell>
  967. <Cell dataKey="说明" style={{ "fontSize": "0.875rem" }}></Cell>
  968. </Column>
  969. </Table>
  970. </EditableContext.Provider>
  971. </CustomProvider>
  972. </Box>
  973. </TabPanel>
  974. <TabPanel value="4">
  975. <div ref={tuijianRef}></div>
  976. </TabPanel>
  977. <TabPanel sx={{p: 1}} value="5">
  978. <Box sx={{maxHeight: `190px`}}>
  979. <FormControl>
  980. <FormLabel id="demo-controlled-radio-buttons-group">说明</FormLabel>
  981. <RadioGroup
  982. aria-labelledby="demo-controlled-radio-buttons-group"
  983. name="controlled-radio-buttons-group"
  984. value={valueYuban}
  985. onChange={onSelectChange2}
  986. >
  987. <FormControlLabel disabled = {!yubanEnable} value="0" control={<Radio />} label={
  988. <Typography sx={{fontSize: "0.875rem"}} >无</Typography>
  989. } />
  990. <FormControlLabel disabled = {!yubanEnable} value="1" control={<Radio />} label={
  991. <Typography sx={{fontSize: "0.875rem"}} >湿拌砂浆</Typography>
  992. } />
  993. <FormControlLabel disabled = {!yubanEnable} value="2" control={<Radio />} label={
  994. <Typography sx={{fontSize: "0.875rem"}} >散装干拌(混)砂浆</Typography>
  995. } />
  996. <FormControlLabel disabled = {!yubanEnable} value="3" control={<Radio />} label={
  997. <Typography sx={{fontSize: "0.875rem"}} >袋装干拌(混)砂浆</Typography>
  998. } />
  999. </RadioGroup>
  1000. </FormControl>
  1001. </Box>
  1002. </TabPanel>
  1003. </TabContext>
  1004. </Box>
  1005. </Stack>
  1006. );
  1007. }