Djcs3.js 57 KB

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