Qufei.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. import * as React from 'react';
  2. import Box from "@mui/material/Box";
  3. import {RichTreeView } from "@mui/x-tree-view/RichTreeView";
  4. import { Grid } from '@mui/material';
  5. import Tab from "@mui/material/Tab";
  6. import TabContext from "@mui/lab/TabContext";
  7. import TabList from "@mui/lab/TabList";
  8. import TabPanel from "@mui/lab/TabPanel";
  9. import Stack from "@mui/material/Stack";
  10. //registerPlugin(NestedRows);
  11. import Service from './Service';
  12. import { Table, ConfigProvider, Button as AButton } from "antd";
  13. import EditableSelect from './EditableSelect';
  14. import EditableSelectGC from './EditableSelectGC';
  15. import Editable from './Editable';
  16. import Button from '@mui/material/Button';
  17. import {copy} from './utils';
  18. export default function Qufei({id, qufeiCallback}) {
  19. const [detail, setDetail] = React.useState([
  20. {"序号": null, "清单编码" : null, "名称" : null,"项目特征" : null,
  21. "计算规则" : null,
  22. "单位" : null,
  23. "数量": null,
  24. "综合单价" : null,
  25. "合价" : null,
  26. "人工费": null,
  27. "主材费" : null,
  28. "设备费": null,
  29. "辅材费": null,
  30. "材料费" : null,
  31. "机械费" : null,
  32. "管理费": null,
  33. "利润": null,
  34. "暂估价" : null,
  35. "综合人工工日" : null,
  36. "备注" : null}]
  37. );
  38. const hotRef = React.useRef(null);
  39. const [expandedRowKeys, setExpandedRowKeys] = React.useState([]);
  40. const [selectedRowKeys, setSelectedRowKeys] = React.useState([]);
  41. const apply = () => {
  42. let checked = check(detail);
  43. if (checked) {
  44. qufeiCallback(id, detail);
  45. }
  46. };
  47. const check = (data) => {
  48. for(let i = 0; i < data.length; i++) {
  49. if (data[i]['管理费(%)'].length == 0) {
  50. return false;
  51. }
  52. if (data[i]['利润(%)'].length == 0) {
  53. return false;
  54. }
  55. if (data[i].hasOwnProperty('children')) {
  56. let checked = check(data[i]['children']);
  57. if (!checked) {
  58. return false;
  59. }
  60. return true;
  61. }
  62. else {
  63. return true;
  64. }
  65. }
  66. };
  67. const rowSelection = {
  68. selectedRowKeys,
  69. onChange: (selectedRowKeys) => {
  70. //console.log(selectedRowKeys);
  71. if (selectedRowKeys.length > 0) {
  72. setExpandedRowKeys([selectedRowKeys.at(-1)]);
  73. } else {
  74. setSelectedRowKeys(selectedRowKeys);
  75. //handleSelection(selectedRowKeys);
  76. }
  77. }
  78. };
  79. const traverse = (data) => {
  80. for(let i = 0; i < data.length; i++) {
  81. if (data[i]['工程类型'].length > 0 && data[i]['工程类别'].length > 0) {
  82. if (data[i]['工程类型'] == '建筑工程') {
  83. if (data[i]['工程类别'] == '一类工程') {
  84. data[i]['管理费(%)'] = '32';
  85. data[i]['利润(%)'] = '12';
  86. data[i]['备注'] = '';
  87. } else if (data[i]['工程类别'] == '二类工程') {
  88. data[i]['管理费(%)'] = '29';
  89. data[i]['利润(%)'] = '12';
  90. data[i]['备注'] = '';
  91. } else {
  92. data[i]['管理费(%)'] = '26';
  93. data[i]['利润(%)'] = '12';
  94. data[i]['备注'] = '';
  95. }
  96. }
  97. if (data[i]['工程类型'] == '单独预制构件制作') {
  98. if (data[i]['工程类别'] == '一类工程') {
  99. data[i]['管理费(%)'] = '15';
  100. data[i]['利润(%)'] = '6';
  101. data[i]['备注'] = '';
  102. } else if (data[i]['工程类别'] == '二类工程') {
  103. data[i]['管理费(%)'] = '13';
  104. data[i]['利润(%)'] = '6';
  105. data[i]['备注'] = '';
  106. } else {
  107. data[i]['管理费(%)'] = '11';
  108. data[i]['利润(%)'] = '6';
  109. data[i]['备注'] = '';
  110. }
  111. }
  112. if (data[i]['工程类型'] == '打预制桩、单独构件吊装') {
  113. if (data[i]['工程类别'] == '一类工程') {
  114. data[i]['管理费(%)'] = '11';
  115. data[i]['利润(%)'] = '5';
  116. data[i]['备注'] = '';
  117. } else if (data[i]['工程类别'] == '二类工程') {
  118. data[i]['管理费(%)'] = '9';
  119. data[i]['利润(%)'] = '5';
  120. data[i]['备注'] = '';
  121. } else {
  122. data[i]['管理费(%)'] = '7';
  123. data[i]['利润(%)'] = '5';
  124. data[i]['备注'] = '';
  125. }
  126. }
  127. if (data[i]['工程类型'] == '制作兼打桩') {
  128. if (data[i]['工程类别'] == '一类工程') {
  129. data[i]['管理费(%)'] = '17';
  130. data[i]['利润(%)'] = '7';
  131. data[i]['备注'] = '';
  132. } else if (data[i]['工程类别'] == '二类工程') {
  133. data[i]['管理费(%)'] = '15';
  134. data[i]['利润(%)'] = '7';
  135. data[i]['备注'] = '';
  136. } else {
  137. data[i]['管理费(%)'] = '12';
  138. data[i]['利润(%)'] = '7';
  139. data[i]['备注'] = '';
  140. }
  141. }
  142. if (data[i]['工程类型'] == '大型土石方工程') {
  143. if (data[i]['工程类别'] == '一类工程') {
  144. data[i]['管理费(%)'] = '7';
  145. data[i]['利润(%)'] = '4';
  146. data[i]['备注'] = '';
  147. } else if (data[i]['工程类别'] == '二类工程') {
  148. data[i]['管理费(%)'] = '7';
  149. data[i]['利润(%)'] = '4';
  150. data[i]['备注'] = '';
  151. } else {
  152. data[i]['管理费(%)'] = '7';
  153. data[i]['利润(%)'] = '4';
  154. data[i]['备注'] = '';
  155. }
  156. }
  157. if (data[i]['工程类型'] == '单独装饰工程') {
  158. if (data[i]['工程类别'] == '一类工程') {
  159. data[i]['管理费(%)'] = '43';
  160. data[i]['利润(%)'] = '15';
  161. data[i]['备注'] = '';
  162. } else if (data[i]['工程类别'] == '二类工程') {
  163. data[i]['管理费(%)'] = '43';
  164. data[i]['利润(%)'] = '15';
  165. data[i]['备注'] = '';
  166. } else {
  167. data[i]['管理费(%)'] = '43';
  168. data[i]['利润(%)'] = '15';
  169. data[i]['备注'] = '';
  170. }
  171. }
  172. if (data[i]['工程类型'] == '安装工程') {
  173. if (data[i]['工程类别'] == '一类工程') {
  174. data[i]['管理费(%)'] = '48';
  175. data[i]['利润(%)'] = '14';
  176. data[i]['备注'] = '计算基础:人工费';
  177. } else if (data[i]['工程类别'] == '二类工程') {
  178. data[i]['管理费(%)'] = '44';
  179. data[i]['利润(%)'] = '14';
  180. data[i]['备注'] = '计算基础:人工费';
  181. } else {
  182. data[i]['管理费(%)'] = '40';
  183. data[i]['利润(%)'] = '14';
  184. data[i]['备注'] = '计算基础:人工费';
  185. }
  186. }
  187. if (data[i]['工程类型'] == '通用项目、道路、排水工程') {
  188. if (data[i]['工程类别'] == '一类工程') {
  189. data[i]['管理费(%)'] = '26';
  190. data[i]['利润(%)'] = '10';
  191. data[i]['备注'] = '';
  192. } else if (data[i]['工程类别'] == '二类工程') {
  193. data[i]['管理费(%)'] = '23';
  194. data[i]['利润(%)'] = '10';
  195. data[i]['备注'] = '';
  196. } else {
  197. data[i]['管理费(%)'] = '20';
  198. data[i]['利润(%)'] = '10';
  199. data[i]['备注'] = '';
  200. }
  201. }
  202. if (data[i]['工程类型'] == '桥梁、水工构筑物') {
  203. if (data[i]['工程类别'] == '一类工程') {
  204. data[i]['管理费(%)'] = '35';
  205. data[i]['利润(%)'] = '10';
  206. data[i]['备注'] = '';
  207. } else if (data[i]['工程类别'] == '二类工程') {
  208. data[i]['管理费(%)'] = '32';
  209. data[i]['利润(%)'] = '10';
  210. data[i]['备注'] = '';
  211. } else {
  212. data[i]['管理费(%)'] = '29';
  213. data[i]['利润(%)'] = '10';
  214. data[i]['备注'] = '';
  215. }
  216. }
  217. if (data[i]['工程类型'] == '给水、燃气与集中供热') {
  218. if (data[i]['工程类别'] == '一类工程') {
  219. data[i]['管理费(%)'] = '45';
  220. data[i]['利润(%)'] = '13';
  221. data[i]['备注'] = '计算基础:人工费';
  222. } else if (data[i]['工程类别'] == '二类工程') {
  223. data[i]['管理费(%)'] = '41';
  224. data[i]['利润(%)'] = '13';
  225. data[i]['备注'] = '计算基础:人工费';
  226. } else {
  227. data[i]['管理费(%)'] = '37';
  228. data[i]['利润(%)'] = '13';
  229. data[i]['备注'] = '计算基础:人工费';
  230. }
  231. }
  232. if (data[i]['工程类型'] == '路灯及交通设施工程') {
  233. if (data[i]['工程类别'] == '一类工程') {
  234. data[i]['管理费(%)'] = '43';
  235. data[i]['利润(%)'] = '13';
  236. data[i]['备注'] = '计算基础:人工费';
  237. } else if (data[i]['工程类别'] == '二类工程') {
  238. data[i]['管理费(%)'] = '43';
  239. data[i]['利润(%)'] = '13';
  240. data[i]['备注'] = '计算基础:人工费';
  241. } else {
  242. data[i]['管理费(%)'] = '43';
  243. data[i]['利润(%)'] = '13';
  244. data[i]['备注'] = '计算基础:人工费';
  245. }
  246. }
  247. if (data[i]['工程类型'] == '(市)大型土石方工程') {
  248. if (data[i]['工程类别'] == '一类工程') {
  249. data[i]['管理费(%)'] = '7';
  250. data[i]['利润(%)'] = '4';
  251. data[i]['备注'] = '';
  252. } else if (data[i]['工程类别'] == '二类工程') {
  253. data[i]['管理费(%)'] = '7';
  254. data[i]['利润(%)'] = '4';
  255. data[i]['备注'] = '';
  256. } else {
  257. data[i]['管理费(%)'] = '7';
  258. data[i]['利润(%)'] = '4';
  259. data[i]['备注'] = '';
  260. }
  261. }
  262. }
  263. if (data[i].hasOwnProperty("children")) {
  264. traverse(data[i]['children']);
  265. }
  266. }
  267. return data;
  268. };
  269. const handleChangeLR = (value) => {
  270. if (selectedRowKeys.length > 0 && detail.length > 0) {
  271. let selected = selectedRowKeys[0];
  272. if (detail[0]['key'] == selected) {
  273. //总选择
  274. let newData = copy(detail);
  275. newData[0]['利润(%)'] = value;
  276. for(let i = 0; i < newData[0]["children"].length; i++) {
  277. let child = newData[0]['children'][i];
  278. child['利润(%)'] = value;
  279. for(let j = 0; j < child['children'].length; j++) {
  280. child['children'][j]['利润(%)'] = value;
  281. }
  282. }
  283. setDetail(newData);
  284. }
  285. else if (detail[0]["children"].filter(x=>x['key'] == selected).length > 0) {
  286. //某个单项工程
  287. let newData = copy(detail);
  288. for(let i = 0; i < newData[0]["children"].length; i++) {
  289. let child = newData[0]['children'][i];
  290. if (child['key'] == selected) {
  291. child['利润(%)'] = value;
  292. for(let j = 0; j < child['children'].length; j++) {
  293. child['children'][j]['利润(%)'] = value;
  294. }
  295. }
  296. }
  297. setDetail(newData);
  298. } else {
  299. //具体一行
  300. let newData = copy(detail);
  301. for(let i = 0; i < newData[0]["children"].length; i++) {
  302. let child = newData[0]['children'][i];
  303. for(let j = 0; j < child['children'].length; j++) {
  304. if (child['children'][j]['key'] == selected) {
  305. child['children'][j]['利润(%)'] = value;
  306. }
  307. }
  308. }
  309. setDetail(newData);
  310. }
  311. }
  312. };
  313. const handleChangeGLF = (value) => {
  314. if (selectedRowKeys.length > 0 && detail.length > 0) {
  315. let selected = selectedRowKeys[0];
  316. if (detail[0]['key'] == selected) {
  317. //总选择
  318. let newData = copy(detail);
  319. newData[0]['管理费(%)'] = value;
  320. for(let i = 0; i < newData[0]["children"].length; i++) {
  321. let child = newData[0]['children'][i];
  322. child['管理费(%)'] = value;
  323. for(let j = 0; j < child['children'].length; j++) {
  324. child['children'][j]['管理费(%)'] = value;
  325. }
  326. }
  327. setDetail(newData);
  328. }
  329. else if (detail[0]["children"].filter(x=>x['key'] == selected).length > 0) {
  330. //某个单项工程
  331. let newData = copy(detail);
  332. for(let i = 0; i < newData[0]["children"].length; i++) {
  333. let child = newData[0]['children'][i];
  334. if (child['key'] == selected) {
  335. child['管理费(%)'] = value;
  336. for(let j = 0; j < child['children'].length; j++) {
  337. child['children'][j]['管理费(%)'] = value;
  338. }
  339. }
  340. }
  341. setDetail(newData);
  342. } else {
  343. //具体一行
  344. let newData = copy(detail);
  345. for(let i = 0; i < newData[0]["children"].length; i++) {
  346. let child = newData[0]['children'][i];
  347. for(let j = 0; j < child['children'].length; j++) {
  348. if (child['children'][j]['key'] == selected) {
  349. child['children'][j]['管理费(%)'] = value;
  350. }
  351. }
  352. }
  353. setDetail(newData);
  354. }
  355. }
  356. };
  357. const handleChange = (value) => {
  358. if (selectedRowKeys.length > 0 && detail.length > 0) {
  359. let selected = selectedRowKeys[0];
  360. if (detail[0]['key'] == selected) {
  361. //总选择
  362. let newData = copy(detail);
  363. newData[0]['工程类别'] = value;
  364. for(let i = 0; i < newData[0]["children"].length; i++) {
  365. let child = newData[0]['children'][i];
  366. child['工程类别'] = value;
  367. for(let j = 0; j < child['children'].length; j++) {
  368. child['children'][j]['工程类别'] = value;
  369. }
  370. }
  371. setDetail(traverse(newData));
  372. }
  373. else if (detail[0]["children"].filter(x=>x['key'] == selected).length > 0) {
  374. //某个单项工程
  375. let newData = copy(detail);
  376. for(let i = 0; i < newData[0]["children"].length; i++) {
  377. let child = newData[0]['children'][i];
  378. if (child['key'] == selected) {
  379. child['工程类别'] = value;
  380. for(let j = 0; j < child['children'].length; j++) {
  381. child['children'][j]['工程类别'] = value;
  382. }
  383. }
  384. }
  385. setDetail(traverse(newData));
  386. } else {
  387. //具体一行
  388. let newData = copy(detail);
  389. for(let i = 0; i < newData[0]["children"].length; i++) {
  390. let child = newData[0]['children'][i];
  391. for(let j = 0; j < child['children'].length; j++) {
  392. if (child['children'][j]['key'] == selected) {
  393. child['children'][j]['工程类别'] = value;
  394. }
  395. }
  396. }
  397. setDetail(traverse(newData));
  398. }
  399. }
  400. };
  401. const handleChangeGC = (value) => {
  402. if (selectedRowKeys.length > 0 && detail.length > 0) {
  403. let selected = selectedRowKeys[0];
  404. if (detail[0]['key'] == selected) {
  405. //总选择
  406. let newData = copy(detail);
  407. newData[0]['工程类型'] = value;
  408. for(let i = 0; i < newData[0]["children"].length; i++) {
  409. let child = newData[0]['children'][i];
  410. child['工程类型'] = value;
  411. for(let j = 0; j < child['children'].length; j++) {
  412. child['children'][j]['工程类型'] = value;
  413. }
  414. }
  415. setDetail(traverse(newData));
  416. }
  417. else if (detail[0]["children"].filter(x=>x['key'] == selected).length > 0) {
  418. //某个单项工程
  419. let newData = copy(detail);
  420. for(let i = 0; i < newData[0]["children"].length; i++) {
  421. let child = newData[0]['children'][i];
  422. if (child['key'] == selected) {
  423. child['工程类型'] = value;
  424. for(let j = 0; j < child['children'].length; j++) {
  425. child['children'][j]['工程类型'] = value;
  426. }
  427. }
  428. }
  429. setDetail(traverse(newData));
  430. } else {
  431. //具体一行
  432. let newData = copy(detail);
  433. for(let i = 0; i < newData[0]["children"].length; i++) {
  434. let child = newData[0]['children'][i];
  435. for(let j = 0; j < child['children'].length; j++) {
  436. if (child['children'][j]['key'] == selected) {
  437. child['children'][j]['工程类型'] = value;
  438. }
  439. }
  440. }
  441. setDetail(traverse(newData));
  442. }
  443. }
  444. };
  445. function selectRow(record) {
  446. /*
  447. const selectedRowKeys_ = [...selectedRowKeys];
  448. if (selectedRowKeys_.indexOf(record.key) >= 0) {
  449. selectedRowKeys_.splice(selectedRowKeys_.indexOf(record.key), 1);
  450. } else {
  451. selectedRowKeys_.push(record.key);
  452. }*/
  453. setSelectedRowKeys([record.key]);
  454. }
  455. React.useEffect(
  456. () => {
  457. Service.generateQufei(id).then(x=>{
  458. setDetail(x);
  459. });
  460. }, [id]
  461. );
  462. return (
  463. <Box>
  464. <Button variant="outlined" onClick={apply}>应用</Button>
  465. <ConfigProvider
  466. theme={{
  467. components: {
  468. Table: {
  469. /* here is your component tokens */
  470. cellPaddingBlock : 8
  471. },
  472. },
  473. }}
  474. >
  475. <Table
  476. dataSource={detail}
  477. //afterSelection={handleSelection}
  478. //afterSelection={handleSelection}
  479. ref = {hotRef}
  480. expandable = {
  481. {
  482. expandedRowKeys,
  483. onExpand: (expandable, record) => {
  484. if (expandable) {
  485. setExpandedRowKeys([...expandedRowKeys, record.key]);
  486. } else {
  487. setExpandedRowKeys(expandedRowKeys.filter((id) => record.key !== id));
  488. }
  489. },
  490. expandRowByClick: true
  491. }
  492. }
  493. rowSelection= {rowSelection}
  494. onRow={(record)=>({
  495. onClick: () => {
  496. selectRow(record);
  497. }
  498. })}
  499. scroll={{ x: 'max-content' , y : 'calc(100vh - 200px)'}}
  500. //pagination={{ position: ['none', 'none'] }}
  501. pagination={false}
  502. columns = {[
  503. { dataIndex: '操作', title : '操作', key : '操作' , width : 30 , fixed: 'left' },
  504. { dataIndex: '名称' , title : '名称' , key : '名称' , width : 250 },
  505. { dataIndex: '工程类型' , title : '工程类型' ,
  506. key : '工程类型' , width : 150 ,
  507. render: (text, record) => {
  508. //console.log("column render");
  509. //console.log("text".concat(text));
  510. //console.log(record);
  511. return (
  512. <EditableSelectGC initialText={text} onChange={handleChangeGC}
  513. >
  514. </EditableSelectGC>
  515. );
  516. //console.log(text);
  517. }
  518. },
  519. { dataIndex: '工程类别' , title : '工程类别' ,
  520. key : '工程类别' , width : 100 ,
  521. render: (text, record) => {
  522. //console.log("column render");
  523. //console.log("text".concat(text));
  524. //console.log(record);
  525. return (
  526. <EditableSelect initialText={text} onChange={handleChange}
  527. >
  528. </EditableSelect>
  529. );
  530. //console.log(text);
  531. }
  532. },
  533. { dataIndex: '管理费(%)' , title : '管理费(%)' , key : '管理费(%)' , width : 50 ,
  534. render: (text, record) => {
  535. //console.log("column render");
  536. //console.log("text".concat(text));
  537. //console.log(record);
  538. return (
  539. <Editable initialText={text} onChange={handleChangeGLF}
  540. >
  541. </Editable>
  542. );
  543. //console.log(text);
  544. } },
  545. { dataIndex: '利润(%)' , title : '利润(%)' , key : '利润(%)' , width : 50 ,
  546. render: (text, record) => {
  547. //console.log("column render");
  548. //console.log("text".concat(text));
  549. //console.log(record);
  550. return (
  551. <Editable initialText={text} onChange={handleChangeLR}
  552. >
  553. </Editable>
  554. );
  555. //console.log(text);
  556. }
  557. },
  558. { dataIndex: '备注', title : '备注', key : '备注' , width : 100 },
  559. ]}
  560. />
  561. </ConfigProvider>
  562. </Box>
  563. );
  564. }