Qingdan3.js 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. import * as React from 'react';
  2. import Box from "@mui/material/Box";
  3. import { Table, ConfigProvider, Button as AButton } from "antd";
  4. import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
  5. import { Grid } from '@mui/material';
  6. import Tab from "@mui/material/Tab";
  7. import TabContext from "@mui/lab/TabContext";
  8. import TabList from "@mui/lab/TabList";
  9. import TabPanel from "@mui/lab/TabPanel";
  10. import Stack from "@mui/material/Stack";
  11. import Service from './Service';
  12. import Button from '@mui/material/Button';
  13. import ButtonGroup from '@mui/material/ButtonGroup';
  14. import {extractFuzhu} from './utils';
  15. import {shanchu, undo, redo, danxiangdinge, updateDercj, changguidinge, handleBeizhu, huan, updateShuliang, handleYuban, updateDeMingcheng} from './editor';
  16. import Backdrop from '@mui/material/Backdrop';
  17. import CircularProgress from '@mui/material/CircularProgress';
  18. import { DataGrid } from '@mui/x-data-grid';
  19. import Dialog from '@mui/material/Dialog';
  20. import DialogTitle from '@mui/material/DialogTitle';
  21. import DialogContent from '@mui/material/DialogContent';
  22. import IconButton from '@mui/material/IconButton';
  23. import Typography from '@mui/material/Typography';
  24. import Editable from './Editable';
  25. import {
  26. SettingFilled,
  27. } from '@ant-design/icons';
  28. import zhCN from 'antd/locale/zh_CN';
  29. import {copy} from './utils';
  30. import {TabulatorFull as Tabulator} from "tabulator-tables"; //import Tabulator library
  31. import "tabulator-tables/dist/css/tabulator.min.css"; //import Tabulator stylesheet
  32. import './Tabulator.css';
  33. /**
  34. *
  35. 本条规定了工程量清单编码的表示方式:十二位阿拉伯数字及其设置规定。
  36. 各位数字的含义是:一、二位为专业工程代码(01—房屋建筑与装饰工程;02—仿古建筑工程;
  37. 03—通用安装工程;04—市政工程;05—园林绿化工程;06—矿山工程;07—构筑物工程;08—城市
  38. 轨道交通工程;09—爆破工程。以后进入国标的专业工程代码以此类推);三、四位为附录分类顺序码;
  39. 五、六位为分部工程顺序码;七、八、九位为分项工程项目名称顺序码;十至十二位为清单项目名称
  40. 顺序码。
  41. */
  42. export default function Qingdan3({name, bh, bt, rgde, jxde, clde, beizhu/*后台传回来的附注信息,要整理后才能成为展示用的行*/ , beizhuFK, clickCallback, loadingCallback, dingeclick, tihuanCallback, tihuanClick, suanshiCallback}) {
  43. const myTable = React.useRef(null);
  44. const myRef = React.useRef(null);
  45. const [valueTab, setValueTab] = React.useState("1");
  46. const handleChange = (event, newValue) => {
  47. setValueTab(newValue);
  48. };
  49. const [rcjhl, setRcjhl] = React.useState([]);
  50. const [rcjhl2, setRcjhl2] = React.useState([]);
  51. const [fuzhu, setFuzhu] = React.useState([]);//展示用的附注行
  52. const [yuban, setYuban] = React.useState([{'key': '0', '说明': '无'}, {'key': '1', '说明': '湿拌砂浆'}, {'key': '2', '说明': '散装干拌(混)砂浆'}, {'key': '3', '说明': '袋装干拌(混)砂浆'}]);
  53. const [tuijian, setTuijian] = React.useState([]);
  54. const [fuzhuEnable, setFuzhuEnable] = React.useState(false);
  55. const [yubanEnable, setYubanEnable] = React.useState(false);
  56. const hotRcjRef = React.useRef(null);
  57. const hotTuijianRef = React.useRef(null);
  58. const highlight = React.useRef([]);
  59. const debmRef = React.useRef(null);
  60. const lastClickRef = React.useRef(null);
  61. const tuijianRef = React.useRef(null);
  62. const tuijianTable = React.useRef(null);
  63. const rcj2Ref = React.useRef(null);
  64. const rcj2Table = React.useRef(null);
  65. const rcjRef = React.useRef(null);
  66. const rcjTable = React.useRef(null);
  67. const [detail, setDetail] = React.useState([
  68. ]);
  69. const selectedRowKeysTable = React.useRef([]);
  70. const selectedRowKeysTableParent = React.useRef(null);
  71. const beizhuFKRef = React.useRef(null);
  72. const rgdeRef = React.useRef(null);
  73. const jxdeRef = React.useRef(null);
  74. const cldeRef = React.useRef(null);
  75. const isQdrcj = React.useRef(false);
  76. const [selectedRowKeys, setSelectedRowKeys] = React.useState([]);
  77. const [selectedRowKeys2, setSelectedRowKeys2] = React.useState([]);
  78. const onSelectChange = (newSelectedRowKeys) => {
  79. console.log('selectedRowKeys changed: ', newSelectedRowKeys);
  80. setSelectedRowKeys(newSelectedRowKeys);
  81. const [newData, newHl] = handleBeizhu(beizhuFKRef.current, selectedRowKeysTable.current[0], newSelectedRowKeys, fuzhu);
  82. if (newData) {
  83. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current));
  84. let y =[];
  85. for (let i = 1; i < newHl.length; i++) {
  86. y.push({
  87. 'ID' : newHl[i][0],
  88. '人材机编码' : newHl[i][1],
  89. '名称' : newHl[i][2],
  90. '规格型号': newHl[i][3],
  91. '单位' : newHl[i][4],
  92. '单价' : newHl[i][5],
  93. '产地' : newHl[i][6],
  94. '供应厂商' : newHl[i][7],
  95. '人材机类别' : newHl[i][8],
  96. '甲供标志': newHl[i][9],
  97. '含量' : newHl[i][10],
  98. '合价' : newHl[i][11],
  99. '暂估价标志' : newHl[i][12],
  100. '主要材料标志' : newHl[i][13],
  101. '主材标志' : newHl[i][14],
  102. '设备标志' : newHl[i][15]
  103. });
  104. }
  105. setRcjhl(y);
  106. if (rcjTable.current) {
  107. rcjTable.current.replaceData(y);
  108. }
  109. }
  110. };
  111. const onSelectChange2 = (newSelectedRowKeys) => {
  112. setSelectedRowKeys2(newSelectedRowKeys);
  113. const [newData, newHl] = handleYuban(selectedRowKeysTable.current[0], newSelectedRowKeys);
  114. if (newData) {
  115. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current));
  116. let y =[];
  117. for (let i = 1; i < newHl.length; i++) {
  118. y.push({
  119. 'ID' : newHl[i][0],
  120. '人材机编码' : newHl[i][1],
  121. '名称' : newHl[i][2],
  122. '规格型号': newHl[i][3],
  123. '单位' : newHl[i][4],
  124. '单价' : newHl[i][5],
  125. '产地' : newHl[i][6],
  126. '供应厂商' : newHl[i][7],
  127. '人材机类别' : newHl[i][8],
  128. '甲供标志': newHl[i][9],
  129. '含量' : newHl[i][10],
  130. '合价' : newHl[i][11],
  131. '暂估价标志' : newHl[i][12],
  132. '主要材料标志' : newHl[i][13],
  133. '主材标志' : newHl[i][14],
  134. '设备标志' : newHl[i][15]
  135. });
  136. }
  137. setRcjhl(y);
  138. if (rcjTable.current) {
  139. rcjTable.current.replaceData(y);
  140. }
  141. }
  142. };
  143. /**fuzhu select */
  144. const rowSelection = {
  145. selectedRowKeys,
  146. onChange: onSelectChange,
  147. getCheckboxProps: (record) => {
  148. return {
  149. disabled: !fuzhuEnable
  150. };
  151. }
  152. };
  153. const rowSelection2 = {
  154. type: 'radio',
  155. selectedRowKeys: selectedRowKeys2,
  156. selections: [Table.SELECTION_NONE],
  157. onChange: onSelectChange2,
  158. getCheckboxProps: (record) => {
  159. return {
  160. disabled: !yubanEnable
  161. };
  162. }
  163. };
  164. var editCheck = function(cell){
  165. //cell - the cell component for the editable cell
  166. //get row data
  167. //console.log(cell);
  168. if(cell._cell.row.data['序号']) return false;
  169. return true;
  170. }
  171. var editCheckRcj = function(cell){
  172. //cell - the cell component for the editable cell
  173. //get row data
  174. //console.log(cell);
  175. if(isQdrcj.current) return false;
  176. return true;
  177. }
  178. var sparklineFormatter = function(cell, formatterParams, onRendered){
  179. for (let i = 0; i < highlight.current.length; i++) {
  180. let entry = highlight.current[i];
  181. if (entry.row + 1 == cell._cell.row.position && entry.col + 1 == cell._cell.column.getPosition()) {
  182. cell.getElement().style.fontWeight = 'bold';
  183. cell.getElement().style.color = 'green';
  184. cell.getElement().style.background = '#d7f1e1';
  185. }
  186. }
  187. return Number(cell.getValue()).toFixed(2).toString();
  188. };
  189. function handleSelect(row){
  190. selectedRowKeysTable.current = [row._row['data']['key']];
  191. if (row._row.data['序号'] != null && row._row.data['序号'].length >0) {
  192. selectedRowKeysTableParent.current = row._row['data']['key'];
  193. setFuzhu([]);
  194. setYubanEnable(false);
  195. setSelectedRowKeys2([]);
  196. Service.generateQingdanrcj(name, bh,bt,row._row.data['清单编码']).then(x=>{
  197. let y =[];
  198. for (let i = 1; i < x.length; i++) {
  199. y.push({
  200. 'ID' : x[i][0],
  201. '人材机编码' : x[i][1],
  202. '名称' : x[i][2],
  203. '规格型号': x[i][3],
  204. '单位' : x[i][4],
  205. '单价' : x[i][5],
  206. '产地' : x[i][6],
  207. '供应厂商' : x[i][7],
  208. '人材机类别' : x[i][8],
  209. '甲供标志': x[i][9],
  210. '含量' : x[i][10],
  211. '合价' : x[i][11],
  212. '暂估价标志' : x[i][12],
  213. '主要材料标志' : x[i][13],
  214. '主材标志' : x[i][14],
  215. '设备标志' : x[i][15]
  216. });
  217. }
  218. setRcjhl(y);
  219. if (rcjTable.current) {
  220. rcjTable.current.replaceData(y);
  221. }
  222. isQdrcj.current = true;
  223. highlight.current = [];
  224. });
  225. Service.generateQingdanTuijian(name, bh,bt,row._row.data['清单编码']).then(x=>{
  226. setTuijian(x);
  227. if (tuijianTable.current) tuijianTable.current.replaceData(x);
  228. });
  229. }else{
  230. setTuijian([]);
  231. if (tuijianTable.current) tuijianTable.current.replaceData([]);
  232. let row_parent = row._row;
  233. while(row_parent.modules.dataTree.parent) {
  234. row_parent = row_parent.modules.dataTree.parent;
  235. }
  236. //console.log(name, bh,bt,qdbm, selected[1]);
  237. debmRef.current = row._row['data']['清单编码'];
  238. selectedRowKeysTableParent.current = row_parent['data']['key'];
  239. let qdbm = row_parent['data']['清单编码'];
  240. let debm = row._row['data']['清单编码'];
  241. console.log('debm=');
  242. console.log(debm);
  243. let danwei = row._row['data']['单位'];
  244. clickCallback(qdbm, debm);
  245. Service.generateDingercj(name, bh,bt,qdbm, debm, danwei).then(x=>{
  246. console.log(x);
  247. let y =[];
  248. for (let i = 1; i < x[0].length; i++) {
  249. y.push({
  250. 'ID' : x[0][i][0],
  251. '人材机编码' : x[0][i][1],
  252. '名称' : x[0][i][2],
  253. '规格型号': x[0][i][3],
  254. '单位' : x[0][i][4],
  255. '单价' : x[0][i][5],
  256. '产地' : x[0][i][6],
  257. '供应厂商' : x[0][i][7],
  258. '人材机类别' : x[0][i][8],
  259. '甲供标志': x[0][i][9],
  260. '含量' : x[0][i][10],
  261. '合价' : x[0][i][11],
  262. '暂估价标志' : x[0][i][12],
  263. '主要材料标志' : x[0][i][13],
  264. '主材标志' : x[0][i][14],
  265. '设备标志' : x[0][i][15]
  266. });
  267. }
  268. setRcjhl(y);
  269. if (rcjTable.current) {
  270. rcjTable.current.replaceData(y);
  271. }
  272. setFuzhuEnable(x[1]);
  273. setYubanEnable(x[1]);
  274. setSelectedRowKeys2(x[2]);
  275. //hotRcjRef.current?.hotInstance?.loadData(x);
  276. isQdrcj.current = false;
  277. let toHighlight = [];
  278. for(let i = 0; i < y.length; i++) {
  279. let entry = y[i];
  280. let bianhao = entry['人材机编码'];
  281. let rcjlb = entry['人材机类别'];
  282. let hit = false;
  283. if (Number(rcjlb) == 1 && rgdeRef.current ) {
  284. for (let j = 0;j < rgdeRef.current.length; j++) {
  285. if (rgdeRef.current[j]["CLBH"] == bianhao) {
  286. if(rgdeRef.current[j]["CLMC"] == entry['名称'])hit = true;
  287. let danjia = Number(entry['单价']);
  288. if (danjia != rgdeRef.current[j]["YSJG"]) {
  289. //console.log(`[${i},5]danjia bu yizhi`);
  290. toHighlight.push({row: i, col: 5, renderer: "customStylesRenderer"});
  291. }
  292. let hanliang = Number(entry['含量']);
  293. if (hanliang != rgdeRef.current[j]["gr"]) {
  294. //console.log(`[${i}, 10]hanliang bu yizhi`);
  295. toHighlight.push({row: i, col: 10, renderer: "customStylesRenderer"});
  296. }
  297. }
  298. }
  299. }
  300. if (Number(rcjlb) == 3 && jxdeRef.current ) {
  301. for (let j = 0; j < jxdeRef.current.length; j++) {
  302. if (jxdeRef.current[j]["jxbh"] == bianhao) {
  303. if(jxdeRef.current[j]["jxmc"] == entry['名称'])hit = true;
  304. let danjia = Number(entry['单价']);
  305. if (danjia != jxdeRef.current[j]["tbdj"]) {
  306. //console.log(`[${i},5]danjia bu yizhi`);
  307. toHighlight.push({row: i, col: 5, renderer: "customStylesRenderer"});
  308. }
  309. let hanliang = Number(entry['含量']);
  310. if (hanliang != jxdeRef.current[j]["sl"]) {
  311. //console.log(`[${i}, 10]hanliang bu yizhi`);
  312. toHighlight.push({row: i, col: 10, renderer: "customStylesRenderer"});
  313. }
  314. }
  315. }
  316. }
  317. if (Number(rcjlb) == 2 && cldeRef.current ) {
  318. for (let j = 0; j < cldeRef.current.length; j++) {
  319. if (cldeRef.current[j]["CLBH"] == bianhao) {
  320. if(cldeRef.current[j]["CLMC"] == entry['名称'])hit = true;
  321. let danjia = Number(entry['单价']);
  322. if (danjia != cldeRef.current[j]["YSJG"]) {
  323. //console.log(`[${i},5]danjia bu yizhi`);
  324. toHighlight.push({row: i, col: 5, renderer: "customStylesRenderer"});
  325. }
  326. let hanliang = Number(entry['含量']);
  327. if (hanliang != cldeRef.current[j]["SL"]) {
  328. //console.log(`[${i}, 10]hanliang bu yizhi`);
  329. toHighlight.push({row: i, col: 10, renderer: "customStylesRenderer"});
  330. }
  331. }
  332. }
  333. }
  334. if (!hit) {
  335. toHighlight.push({row: i, col: 1, renderer: "customStylesRenderer"});
  336. }
  337. }
  338. highlight.current = toHighlight;
  339. });
  340. }
  341. }
  342. React.useEffect(() => {
  343. myTable.current = new Tabulator(myRef.current, {
  344. index: "key",
  345. height: 380,
  346. data: detail, //link data to table
  347. reactiveData: false, //enable data reactivity
  348. dataTreeStartExpanded:true,
  349. dataTree: true,
  350. selectableRows:1, //make rows selectable
  351. editTriggerEvent:"dblclick", //trigger edit on double click
  352. dataTreeStartExpanded:function(row, level){
  353. //console.log(row);
  354. //console.log(level);
  355. return true; //expand rows where the "driver" data field is true;
  356. },
  357. columns: [ //Define Table Columns
  358. {title:"序号", field:"序号", width:80, headerSort:false, frozen: true}, //never hide this column
  359. {title:"清单编码", field:"清单编码", width:120,headerSort:false, frozen: true ,formatter:"textarea" },
  360. {title:"名称", field:"名称", width:150, headerSort:false, formatter:"textarea", editor: "input", editable: editCheck}, //hide this column first
  361. {title:"项目特征", field:"项目特征", width:150 , headerSort:false, formatter:"textarea"},
  362. {title:"计算规则", field:"计算规则", width:150, headerSort:false, formatter:"textarea"},
  363. {title:"单位", field:"单位", width:100, headerSort:false},
  364. {title:"数量", field:"数量", width:100, headerSort:false, editor: "input", editable: editCheck },
  365. {title:"综合单价", field:"综合单价", width:100, headerSort:false, formatter:"money"},
  366. {title:"合价", field:"合价", width:100, headerSort:false, formatter:"money"},
  367. {title:"人工费", field:"人工费", width:100, headerSort:false, formatter:"money"},
  368. {title:"主材费", field:"主材费", width:100, headerSort:false, formatter:"money"},
  369. {title:"设备费", field:"设备费", width:100, headerSort:false, formatter:"money"},
  370. {title:"辅材费", field:"辅材费", width:100, headerSort:false, formatter:"money"},
  371. {title:"材料费", field:"材料费", width:100, headerSort:false, formatter:"money"},
  372. {title:"机械费", field:"机械费", width:100, headerSort:false, formatter:"money"},
  373. {title:"管理费", field:"管理费", width:100, headerSort:false, formatter:"money"},
  374. {title:"利润", field:"利润", width:100, headerSort:false, formatter:"money"},
  375. {title:"暂估价", field:"暂估价", width:100, headerSort:false, formatter:"money"},
  376. {title:"综合人工工日", field:"综合人工工日", width:100, headerSort:false},
  377. ]
  378. });
  379. myTable.current.on("cellDblClick", function(e, cell){
  380. //e - the click event object
  381. //cell - cell component
  382. console.log(cell);
  383. });
  384. myTable.current.on("rowSelected", handleSelect);
  385. myTable.current.on("cellEdited", function(cell){
  386. //console.log("edited");
  387. //console.log();
  388. let key = cell._cell.row.data['key'];
  389. myTable.current.deselectRow();
  390. if(cell._cell.column.field == '名称') {
  391. let newData = updateDeMingcheng(cell._cell.row.data['名称'], selectedRowKeysTable.current[0]);
  392. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function() {
  393. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  394. let component = null;
  395. for(let i = 0; i < getRow.length; i++) {
  396. let entry = getRow[i]._row.modules.dataTree.children;
  397. for(let j = 0; j < entry.length; j++) {
  398. let child = entry[j];
  399. if(child.data['key'] == key) {
  400. //console.log(child);
  401. component = child.component;
  402. break;
  403. }
  404. }
  405. }
  406. component.select();
  407. handleSelect(component);
  408. //handleSelect(getRow[0]);
  409. });
  410. }
  411. else{
  412. let [success, data] = updateShuliang(cell._cell.row.data['数量'], selectedRowKeysTable.current[0]);
  413. if (success) {
  414. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function() {
  415. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  416. let component = null;
  417. for(let i = 0; i < getRow.length; i++) {
  418. let entry = getRow[i]._row.modules.dataTree.children;
  419. for(let j = 0; j < entry.length; j++) {
  420. let child = entry[j];
  421. if(child.data['key'] == key) {
  422. //console.log(child);
  423. component = child.component;
  424. break;
  425. }
  426. }
  427. }
  428. component.select();
  429. handleSelect(component);
  430. //handleSelect(getRow[0]);
  431. });
  432. }
  433. }
  434. });
  435. myTable.current.on("tableBuilt", () => {
  436. Service.generateQingdanmingxi(name, bh, bt).then(x=>{
  437. myTable.current.replaceData(x);
  438. });
  439. });
  440. }, [bh, bt]);
  441. React.useEffect(
  442. () => {
  443. //console.log("rgde changed");
  444. //console.log(rgde);
  445. rgdeRef.current = rgde;
  446. jxdeRef.current = jxde;
  447. cldeRef.current = clde;
  448. if (isQdrcj.current) {
  449. highlight.current = [];
  450. } else {
  451. let toHighlight = [];
  452. for(let i = 0; i < rcjhl.length; i++) {
  453. let entry = rcjhl[i];
  454. let bianhao = entry['人材机编码'];
  455. let rcjlb = entry['人材机类别'];
  456. let hit = false;
  457. if (Number(rcjlb) == Number(1) && rgde) {
  458. for (let j = 0; j < rgde.length; j++) {
  459. if (rgde[j]["CLBH"] == bianhao) {
  460. if(rgde[j]["CLMC"] == entry['名称'])hit = true;
  461. let danjia = Number(entry['单价']);
  462. if (danjia != rgde[j]["YSJG"]) {
  463. //console.log(`[${i},5]danjia bu yizhi`);
  464. toHighlight.push({row: i, col: 5, renderer: "customStylesRenderer"});
  465. }
  466. let hanliang = Number(entry['含量']);
  467. if (hanliang != rgde[j]["gr"]) {
  468. //console.log(`[${i}, 10]hanliang bu yizhi`);
  469. toHighlight.push({row: i, col: 10, renderer: "customStylesRenderer"});
  470. }
  471. }
  472. }
  473. }
  474. if (Number(rcjlb) == Number(3) && jxde ) {
  475. for (let j = 0; j < jxde.length; j++) {
  476. if (jxde[j]["jxbh"] == bianhao) {
  477. if(jxde[j]["jxmc"] == entry['名称'])hit = true;
  478. let danjia = Number(entry['单价']);
  479. if (danjia != jxde[j]["tbdj"]) {
  480. //console.log(`[${i},5]danjia bu yizhi`);
  481. toHighlight.push({row: i, col: 5, renderer: "customStylesRenderer"});
  482. }
  483. let hanliang = Number(entry['含量']);
  484. if (hanliang != jxde[j]["sl"]) {
  485. //console.log(`[${i}, 10]hanliang bu yizhi`);
  486. toHighlight.push({row: i, col: 10, renderer: "customStylesRenderer"});
  487. }
  488. }
  489. }
  490. }
  491. if (Number(rcjlb) == Number(2) && clde ) {
  492. for (let j = 0; j < clde.length; j++) {
  493. if (clde[j]["CLBH"] == bianhao) {
  494. if(clde[j]["CLMC"] == entry['名称'])hit = true;
  495. let danjia = Number(entry['单价']);
  496. if (danjia != clde[j]["YSJG"]) {
  497. //console.log(`[${i},5]danjia bu yizhi`);
  498. toHighlight.push({row: i, col: 5, renderer: "customStylesRenderer"});
  499. }
  500. let hanliang = Number(entry['含量']);
  501. if (hanliang != clde[j]["SL"]) {
  502. //console.log(`[${i}, 10]hanliang bu yizhi`);
  503. toHighlight.push({row: i, col: 10, renderer: "customStylesRenderer"});
  504. }
  505. }
  506. }
  507. }
  508. if (!hit) {
  509. toHighlight.push({row: i, col: 1, renderer: "customStylesRenderer"});
  510. }
  511. }
  512. //console.log(toHighlight);
  513. highlight.current = toHighlight;
  514. }
  515. let bzrcjhl = [/*["人材机编码", "名称", "单位", "单价", "合价", "含量"]*/]
  516. if (rgde)
  517. for (let i = 0; i < rgde.length; i++) {
  518. bzrcjhl.push({'人材机编码': rgde[i]["CLBH"], '名称': rgde[i]["CLMC"], '单位': rgde[i]["JLDW"], '单价': rgde[i]["YSJG"], '合价': rgde[i]["gf"], '含量': rgde[i]["gr"]});
  519. }
  520. if (clde)
  521. for (let i = 0; i < clde.length; i++) {
  522. bzrcjhl.push({'人材机编码': clde[i]["CLBH"], '名称': clde[i]["CLMC"], '单位': clde[i]["JLDW"], '单价': clde[i]["YSJG"], '合价': clde[i]["HJ"], '含量': clde[i]["SL"]});
  523. }
  524. if (jxde)
  525. for (let i = 0; i < jxde.length; i++) {
  526. bzrcjhl.push({'人材机编码': jxde[i]["jxbh"], '名称': jxde[i]["jxmc"], '单位': jxde[i]["DW"], '单价': jxde[i]["tbdj"], '合价': jxde[i]["hj"], '含量': jxde[i]["sl"]});
  527. }
  528. setRcjhl2(bzrcjhl);
  529. }, [rgde, jxde, clde]
  530. );
  531. React.useEffect(
  532. () => {
  533. console.log(beizhu);
  534. let result = [];
  535. if (beizhu != null) {
  536. let keys = Object.keys(beizhu["BZBH"]);
  537. for(let i = 0; i < keys.length; i++) {
  538. let key = keys[i];
  539. result.push({'key': i+1, '序号': i+1, '编号': beizhu["BZBH"][key], '说明': beizhu["SM"][key]});//序号很重要
  540. }
  541. setFuzhu(result);
  542. let newSelect = extractFuzhu(debmRef.current);
  543. setSelectedRowKeys(newSelect);
  544. //setSelectedRowKeys([1]);
  545. }
  546. }, [beizhu]
  547. );
  548. React.useEffect(
  549. () => {
  550. beizhuFKRef.current = beizhuFK;
  551. }, [beizhuFK]
  552. );
  553. React.useEffect(
  554. () => {
  555. myTable.current.deselectRow();
  556. //console.log(dingeclick);
  557. if (selectedRowKeysTable.current.length > 0 ) {
  558. const [success, data, key] = changguidinge(JSON.parse(dingeclick), selectedRowKeysTable.current[0]);
  559. if (success) {
  560. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  561. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  562. let component = null;
  563. for(let i = 0; i < getRow.length; i++) {
  564. let entry = getRow[i]._row.modules.dataTree.children;
  565. for(let j = 0; j < entry.length; j++) {
  566. let child = entry[j];
  567. if(child.data['key'] == key) {
  568. //console.log(child);
  569. component = child.component;
  570. break;
  571. }
  572. }
  573. }
  574. component.select();
  575. handleSelect(component);
  576. });
  577. }
  578. }
  579. }, [dingeclick]//常规添加定额
  580. );
  581. React.useEffect(
  582. () => {
  583. //console.log(dingeclick);
  584. if (selectedRowKeysTable.current.length > 0 ) {
  585. const data = huan(JSON.parse(tihuanClick), selectedRowKeysTable.current[0]);
  586. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  587. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  588. let component = null;
  589. for(let i = 0; i < getRow.length; i++) {
  590. let entry = getRow[i]._row.modules.dataTree.children;
  591. for(let j = 0; j < entry.length; j++) {
  592. let child = entry[j];
  593. if(child.data['key'] == selectedRowKeysTable.current[0]) {
  594. //console.log(child);
  595. component = child.component;
  596. break;
  597. }
  598. }
  599. }
  600. handleSelect(component);
  601. });
  602. }
  603. }, [tihuanClick]//替换定额人材机
  604. );
  605. React.useEffect(
  606. () => {
  607. if (tuijianRef.current != null ) {
  608. tuijianTable.current = new Tabulator(tuijianRef.current, {
  609. index: "key",
  610. height: 200,
  611. data: tuijian, //link data to table
  612. reactiveData: false, //enable data reactivity
  613. dataTreeStartExpanded:false,
  614. dataTree: false,
  615. selectableRows:1, //make rows selectable
  616. columns: [ //Define Table Columns
  617. {title:"ID", field:"ID", width:80, headerSort:false, }, //never hide this column
  618. {title:"定额编号", field:"定额编号", width:120,headerSort:false, formatter:"textarea" },
  619. {title:"工程量名称", field:"工程量名称", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
  620. {title:"工作内容", field:"工作内容", width:150 , headerSort:false, formatter:"textarea"},
  621. ]
  622. });
  623. tuijianTable.current.on("tableBuilt", () => {
  624. tuijianTable.current.replaceData(tuijian);
  625. });
  626. }
  627. if (rcj2Ref.current != null ) {
  628. rcj2Table.current = new Tabulator(rcj2Ref.current, {
  629. index: "key",
  630. height: 200,
  631. data: rcjhl2, //link data to table
  632. reactiveData: false, //enable data reactivity
  633. dataTreeStartExpanded:false,
  634. dataTree: false,
  635. selectableRows:1, //make rows selectable
  636. columns: [ //Define Table Columns
  637. {title:"人材机编码", field:"人材机编码", width:80, headerSort:false, }, //never hide this column
  638. {title:"名称", field:"名称", width:120,headerSort:false, formatter:"textarea" },
  639. {title:"单位", field:"单位", width:150, headerSort:false, formatter:"textarea"}, //hide this column first
  640. {title:"单价", field:"单价", width:150 , headerSort:false, formatter:"money"},
  641. {title:"合价", field:"合价", width:150 , headerSort:false, formatter:"money"},
  642. {title:"含量", field:"含量", width:150 , headerSort:false, formatter:"textarea"},
  643. ]
  644. });
  645. rcj2Table.current.on("tableBuilt", () => {
  646. rcj2Table.current.replaceData(rcjhl2);
  647. });
  648. }
  649. if (rcjRef.current != null ) {
  650. rcjTable.current = new Tabulator(rcjRef.current, {
  651. index: "key",
  652. height: 200,
  653. data: rcjhl, //link data to table
  654. reactiveData: false, //enable data reactivity
  655. dataTreeStartExpanded:false,
  656. dataTree: false,
  657. selectableRows:1, //make rows selectable
  658. editTriggerEvent:"dblclick",
  659. columns: [ //Define Table Columns
  660. {title:"ID", field:"ID", width:80, headerSort:false, },
  661. {title:"人材机编码", field:"人材机编码", width:80, headerSort:false, }, //never hide this column
  662. {title:"名称", field:"名称", width:120,headerSort:false, formatter:"textarea", editor: "input", editable: editCheckRcj },
  663. {title:"规格型号", field:"规格型号", width:80, headerSort:false, editor: "input", editable: editCheckRcj },
  664. {title:"单位", field:"单位", width:80, headerSort:false, formatter:"textarea"}, //hide this column first
  665. {title:"单价", field:"单价", width:80 , headerSort:false, formatter: sparklineFormatter, editor: "input", editable: editCheckRcj },
  666. {title:"产地", field:"产地", width:80, headerSort:false, },
  667. {title:"供应厂商", field:"供应厂商", width:80, headerSort:false, },
  668. {title:"人材机类别", field:"人材机类别", width:80, headerSort:false, },
  669. {title:"甲供标志", field:"甲供标志", width:80 , headerSort:false, formatter:"textarea"},
  670. {title:"含量", field:"含量", width:80 , headerSort:false, formatter:"money", formatterParams:{precision:4}, editor: "input", editable: editCheckRcj },
  671. {title:"合价", field:"合价", width:80 , headerSort:false, formatter:"money"},
  672. {title:"暂估价标志", field:"暂估价标志", width:80 , headerSort:false, formatter:"textarea"},
  673. {title:"主要材料标志", field:"主要材料标志", width:100 , headerSort:false, formatter:"textarea"},
  674. {title:"主材标志", field:"主材标志", width:80 , headerSort:false, formatter:"textarea"},
  675. {title:"设备标志", field:"设备标志", width:80 , headerSort:false, formatter:"textarea"},
  676. ]
  677. });
  678. rcjTable.current.on("tableBuilt", () => {
  679. rcjTable.current.replaceData(rcjhl);
  680. });
  681. rcjTable.current.on("cellDblClick", function(e, cell){
  682. //e - the click event object
  683. //cell - cell component
  684. if(cell._cell.column.getPosition() == 2 && !isQdrcj.current) {
  685. tihuanCallback(cell._cell.row.position, cell._cell.column.getPosition());
  686. }
  687. });
  688. rcjTable.current.on("cellEdited", function(cell){
  689. let data = copy(cell._cell.table.getData());
  690. for(let i = 0; i < data.length; i++) {
  691. data[i]['合价'] = Number(data[i]['单价']) * Number(data[i]['含量']);
  692. }
  693. setRcjhl(data);
  694. if (rcjTable.current) {
  695. rcjTable.current.replaceData(data);
  696. }
  697. let data2 = [['ID', '人材机编码', '名称', '规格型号', '单位', '单价', '产地', '供应厂商', '人材机类别', '甲供标志', '含量', '合价', '暂估价标志', '主要材料标志', '主材标志', '设备标志']]
  698. for (let i = 0; i < data.length; i++) {
  699. data2.push([data[i]['ID'], data[i]['人材机编码'], data[i]['名称'], data[i]['规格型号'], data[i]['单位'],
  700. data[i]['单价'], data[i]['产地'], data[i]['供应厂商'], data[i]['人材机类别'],
  701. data[i]['甲供标志'], data[i]['含量'], data[i]['合价'], data[i]['暂估价标志'], data[i]['主要材料标志'], data[i]['主材标志'], data[i]['设备标志']]);
  702. }
  703. let newData = updateDercj(selectedRowKeysTable.current[0], data2);
  704. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function() {
  705. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  706. let component = null;
  707. for(let i = 0; i < getRow.length; i++) {
  708. let entry = getRow[i]._row.modules.dataTree.children;
  709. for(let j = 0; j < entry.length; j++) {
  710. let child = entry[j];
  711. if(child.data['key'] == selectedRowKeysTable.current[0]) {
  712. //console.log(child);
  713. component = child.component;
  714. break;
  715. }
  716. }
  717. }
  718. handleSelect(component);
  719. });
  720. });
  721. }
  722. }, [valueTab]
  723. );
  724. return (
  725. <Stack spacing={2}>
  726. <Box>
  727. <Stack direction='row' spacing={2}>
  728. <Button variant="outlined" size="small" onClick={() => {
  729. if (selectedRowKeysTable.current.length > 0) {
  730. let getRow = myTable.current.getRows(); //get array of currently selected row components.
  731. let hit = false;
  732. for(let i = 0; i < getRow.length; i++) {
  733. if (getRow[i]._row.data['key'] == selectedRowKeysTable.current[0]) {
  734. hit = true;
  735. }
  736. }
  737. if (hit) {
  738. suanshiCallback();
  739. }
  740. }
  741. }}
  742. >定额(算式)</Button>
  743. <Button variant="outlined" size="small" onClick={() => {
  744. if (selectedRowKeysTable.current.length > 0) {
  745. const [success, data] = danxiangdinge(selectedRowKeysTable.current[0]);
  746. if(success) {
  747. myTable.current.updateData(data.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  748. selectedRowKeysTable.current = [];
  749. selectedRowKeysTableParent.current = null;
  750. setRcjhl([]);
  751. if (rcjTable.current) {
  752. rcjTable.current.replaceData([]);
  753. }
  754. setFuzhu([]);
  755. setSelectedRowKeys2([]);
  756. setYubanEnable(false);
  757. isQdrcj.current = true;
  758. highlight.current = [];
  759. });
  760. }
  761. }
  762. }}
  763. >单项定额</Button>
  764. <Button variant="outlined" size="small" onClick={() => {
  765. if (selectedRowKeysTable.current.length > 0) {
  766. let newData = shanchu(selectedRowKeysTable.current[0]);
  767. myTable.current.updateData(newData.filter(x=>x['key'] == selectedRowKeysTableParent.current)).then(function(){
  768. if (newData.filter(x=>x['key'] == selectedRowKeysTable.current[0]).length == 0) {
  769. selectedRowKeysTable.current = [];
  770. selectedRowKeysTableParent.current = [];
  771. setRcjhl([]);
  772. if (rcjTable.current) {
  773. rcjTable.current.replaceData([]);
  774. }
  775. setFuzhu([]);
  776. setSelectedRowKeys2([]);
  777. setYubanEnable(false);
  778. isQdrcj.current = true;
  779. highlight.current = [];
  780. }
  781. });
  782. }
  783. }}
  784. >删除</Button>
  785. <Button variant="outlined" size="small" onClick={() => {
  786. let newData = undo();
  787. myTable.current.updateData(newData).then(function(){
  788. selectedRowKeysTable.current = [];
  789. selectedRowKeysTableParent.current = null;
  790. setRcjhl([]);
  791. if (rcjTable.current) {
  792. rcjTable.current.replaceData([]);
  793. }
  794. setFuzhu([]);
  795. setSelectedRowKeys2([]);
  796. setYubanEnable(false);
  797. isQdrcj.current = true;
  798. highlight.current = [];
  799. });
  800. }}
  801. >撤销</Button>
  802. <Button variant="outlined" size="small" onClick={() => {
  803. let newData = redo();
  804. myTable.current.updateData(newData).then(function(){
  805. selectedRowKeysTable.current = [];
  806. selectedRowKeysTableParent.current = null;
  807. setRcjhl([]);
  808. if (rcjTable.current) {
  809. rcjTable.current.replaceData([]);
  810. }
  811. setFuzhu([]);
  812. setSelectedRowKeys2([]);
  813. setYubanEnable(false);
  814. isQdrcj.current = true;
  815. highlight.current = [];
  816. });
  817. }}
  818. >重做</Button>
  819. <Button variant="outlined" size="small" onClick={() => {
  820. console.log("save to cloud");
  821. loadingCallback();
  822. }}
  823. >保存</Button>
  824. </Stack>
  825. <div ref={myRef}>
  826. </div>
  827. </Box>
  828. <Box >
  829. <TabContext value={valueTab}>
  830. <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
  831. <TabList sx={{minHeight: '24px'}} onChange={handleChange} aria-label="lab API tabs example">
  832. <Tab sx={{p: 0, minHeight: '24px'}} label="人材机含量" value="1" />
  833. <Tab sx={{p: 0, minHeight: '24px'}} label="标准定额人材机含量" value="2" />
  834. <Tab sx={{p: 0, minHeight: '24px'}} label="定额附注" value="3" />
  835. <Tab sx={{p: 0, minHeight: '24px'}} label="预拌砂浆" value="4" />
  836. <Tab sx={{p: 0, minHeight: '24px'}} label="组价推荐" value="5" />
  837. </TabList>
  838. </Box>
  839. <TabPanel sx={{p: 1}} value="1">
  840. <div ref={rcjRef}></div>
  841. </TabPanel>
  842. <TabPanel sx={{p: 1}} value="2">
  843. <div ref={rcj2Ref}></div>
  844. </TabPanel>
  845. <TabPanel sx={{p: 1}} value="3">
  846. <Box sx={{maxHeight: `190px`}}>
  847. <ConfigProvider
  848. locale={zhCN}
  849. theme={{
  850. components: {
  851. Table: {
  852. /* here is your component tokens */
  853. cellPaddingBlock : 8
  854. },
  855. },
  856. }}
  857. >
  858. <Table
  859. scroll={{ x: 'max-content' , y : 190}}
  860. pagination={false}
  861. rowSelection={rowSelection}
  862. columns={
  863. [
  864. { title: '序号', dataIndex: '序号', width : 80},
  865. {
  866. title: '编号',
  867. dataIndex: '编号',
  868. },
  869. {
  870. title: '说明',
  871. dataIndex: '说明',
  872. width: 550
  873. },
  874. ]
  875. }
  876. dataSource={fuzhu} />
  877. </ConfigProvider>
  878. </Box>
  879. </TabPanel>
  880. <TabPanel sx={{p: 1}} value="4">
  881. <Box sx={{maxHeight: `190px`}}>
  882. <ConfigProvider
  883. locale={zhCN}
  884. theme={{
  885. components: {
  886. Table: {
  887. /* here is your component tokens */
  888. cellPaddingBlock : 8
  889. },
  890. },
  891. }}
  892. >
  893. <Table
  894. scroll={{ x: 'max-content' , y : 190}}
  895. pagination={false}
  896. rowSelection={rowSelection2}
  897. columns={
  898. [
  899. {
  900. title: '说明',
  901. dataIndex: '说明',
  902. width: 550
  903. },
  904. ]
  905. }
  906. dataSource={yuban} />
  907. </ConfigProvider>
  908. </Box>
  909. </TabPanel>
  910. <TabPanel sx={{p: 1}} value="5">
  911. <div ref={tuijianRef}></div>
  912. </TabPanel>
  913. </TabContext>
  914. </Box>
  915. </Stack>
  916. );
  917. }