detail.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. import PageContent from '@/components/PageContent';
  2. import { Button, Tabs, Space, Drawer, Timeline, message } from 'antd';
  3. import styles from './index.less';
  4. import { useEffect, useMemo, useRef, useState } from 'react';
  5. import axios from 'axios';
  6. import {
  7. useLocation,
  8. useParams,
  9. useRequest,
  10. useSearchParams,
  11. useNavigate,
  12. useModel,
  13. } from '@umijs/max';
  14. import {
  15. queryPsrExcel,
  16. queryPsrExcelList,
  17. queryPsrMonthDetail,
  18. queryPsrMonthLast,
  19. queryPsrMonthList,
  20. queryPsrWorkLoad,
  21. querySavePsrMonth,
  22. } from '../../services/psr';
  23. import SaveModal from './components/saveOtherModal';
  24. import CompareModal from './components/compareModal';
  25. import CompareCom from './components/compareCom';
  26. import dayjs from 'dayjs';
  27. import { getToken } from '@/utils/utils';
  28. import { exportExcel, getUUID } from '../../utils/exportExcl';
  29. import { stringify } from 'qs';
  30. import LuckyExcel from 'luckyexcel';
  31. const ZeroNineType = {
  32. Equipment: '09-010', //设备费
  33. Production: '09-020', //金科制造中心设备制造费
  34. UF: '09-030', //金科制造中心-UF膜(
  35. AI: '09-040', //数字双胞胎
  36. Install: '09-050', //安装分包费用(包括增值税)
  37. Construction: '09-060', //土建分包费用(包括增值税)
  38. };
  39. const preActConfig = [
  40. {
  41. type: ZeroNineType.Equipment,
  42. originC: 6,
  43. originR: { begin: 6, end: 297 }, //总的减上面所有的
  44. fill: { c: 5, r: 36 },
  45. num: 293,
  46. },
  47. {
  48. type: ZeroNineType.Production,
  49. originC: 6,
  50. originR: { begin: 17, end: 27 },
  51. //填充到psr表中的位置
  52. fill: { c: 5, r: 37 },
  53. num: 301,
  54. },
  55. {
  56. type: ZeroNineType.UF,
  57. originC: 6,
  58. originR: { begin: 6, end: 16 },
  59. fill: { c: 5, r: 38 },
  60. num: 309,
  61. },
  62. {
  63. type: ZeroNineType.AI,
  64. originC: 6,
  65. originR: { begin: 172, end: 192 },
  66. fill: { c: 5, r: 39 },
  67. num: 317,
  68. },
  69. {
  70. type: ZeroNineType.Install,
  71. originC: 6,
  72. originR: { begin: 214, end: 224 },
  73. fill: { c: 5, r: 40 },
  74. num: 325,
  75. },
  76. {
  77. type: ZeroNineType.Construction,
  78. originC: 6,
  79. originR: { begin: 214, end: 224 },
  80. fill: { c: 5, r: 41 },
  81. num: 333,
  82. },
  83. {
  84. type: ZeroNineType.Equipment,
  85. originC: 8,
  86. originR: { begin: 6, end: 297 }, //总的减上面所有的
  87. fill: { c: 3, r: 36 },
  88. num: 291,
  89. },
  90. {
  91. type: ZeroNineType.Production,
  92. originC: 8,
  93. originR: { begin: 17, end: 27 },
  94. //填充到psr表中的位置
  95. fill: { c: 3, r: 37 },
  96. num: 299,
  97. },
  98. {
  99. type: ZeroNineType.UF,
  100. originC: 8,
  101. originR: { begin: 6, end: 16 },
  102. fill: { c: 3, r: 38 },
  103. num: 307,
  104. },
  105. {
  106. type: ZeroNineType.AI,
  107. originC: 8,
  108. originR: { begin: 172, end: 192 },
  109. fill: { c: 3, r: 39 },
  110. num: 315,
  111. },
  112. {
  113. type: ZeroNineType.Install,
  114. originC: 8,
  115. originR: { begin: 214, end: 224 },
  116. fill: { c: 3, r: 40 },
  117. num: 323,
  118. },
  119. {
  120. type: ZeroNineType.Construction,
  121. originC: 8,
  122. originR: { begin: 214, end: 224 },
  123. fill: { c: 3, r: 41 },
  124. num: 331,
  125. },
  126. ];
  127. const curMonthConfig = [
  128. {
  129. type: ZeroNineType.Equipment,
  130. originC: null,
  131. originR: { begin: 6, end: 297 }, //总的减上面所有的
  132. fill: { c: 7, r: 36 },
  133. num: 295,
  134. },
  135. {
  136. type: ZeroNineType.Production,
  137. originC: null, //需要计算的出,当前表单是第几月,取当月的那列
  138. originR: { begin: 17, end: 27 },
  139. fill: { c: 7, r: 37 },
  140. num: 303,
  141. },
  142. {
  143. type: ZeroNineType.UF,
  144. originC: null,
  145. originR: { begin: 6, end: 16 },
  146. fill: { c: 7, r: 38 },
  147. num: 311,
  148. },
  149. {
  150. type: ZeroNineType.AI,
  151. originC: null,
  152. originR: { begin: 172, end: 192 },
  153. fill: { c: 7, r: 39 },
  154. num: 319,
  155. },
  156. {
  157. type: ZeroNineType.Install,
  158. originC: null,
  159. originR: { begin: 214, end: 224 },
  160. fill: { c: 7, r: 40 },
  161. num: 327,
  162. },
  163. {
  164. type: ZeroNineType.Construction,
  165. originC: null,
  166. originR: { begin: 214, end: 224 },
  167. fill: { c: 7, r: 41 },
  168. num: 335,
  169. },
  170. ];
  171. const workConfig = [
  172. {
  173. code: '02-010',
  174. fill: { r: 7, actC: 3, curC: 7 }, // actC实际支出 curC当月发生额
  175. },
  176. {
  177. code: '04-010',
  178. fill: { r: 11, actC: 3, curC: 7 },
  179. },
  180. {
  181. code: '05-010',
  182. fill: { r: 16, actC: 3, curC: 7 },
  183. },
  184. {
  185. code: '06-010',
  186. fill: { r: 24, actC: 3, curC: 7 },
  187. },
  188. {
  189. code: '07-010',
  190. fill: { r: 28, actC: 3, curC: 7 },
  191. },
  192. {
  193. code: '08-010',
  194. fill: { r: 32, actC: 3, curC: 7 },
  195. },
  196. {
  197. code: '10-010',
  198. fill: { r: 44, actC: 3, curC: 7 },
  199. },
  200. {
  201. code: '11-010',
  202. fill: { r: 59, actC: 3, curC: 7 },
  203. },
  204. {
  205. code: '11-030',
  206. fill: { r: 61, actC: 3, curC: 7 },
  207. },
  208. {
  209. code: '11-050',
  210. fill: { r: 63, actC: 3, curC: 7 },
  211. },
  212. ];
  213. const PSRDetail = () => {
  214. const { initialState } = useModel('@@initialState');
  215. const user = initialState?.user || {};
  216. const navigate = useNavigate();
  217. const params = useParams();
  218. const location = useLocation();
  219. const token = getToken();
  220. const { id: projectId } = params;
  221. const {
  222. state: { project_name, flow_id, node_id, init_flow_id },
  223. } = location;
  224. const [historyList, setHistoryList] = useState([]);
  225. const [excelData, setExcelData] = useState();
  226. const [historyOpen, setHistoryOpen] = useState();
  227. const [open, setOpen] = useState(false);
  228. const [key, setKey] = useState();
  229. const [compareOpen, setCompareOpen] = useState(false);
  230. const [compareValues, setCompareValues] = useState([]);
  231. const [isOriginVer, setIsOriginVer] = useState(false); //是否原始版本 是的话只能另存不能编辑
  232. const [noData, setNoData] = useState(false); //是否展示导出按钮
  233. const titleRef = useRef('');
  234. const luckysheetRef = useRef();
  235. const iframeRef = useRef();
  236. const unableEdit = (option) => {
  237. option.showtoolbar = false;
  238. option.enableAddRow = false;
  239. option.sheetFormulaBar = false;
  240. option.enableAddBackTop = false;
  241. option.showsheetbarConfig = {
  242. add: false,
  243. sheet: false,
  244. };
  245. option.cellRightClickConfig = {
  246. copy: false, // 复制
  247. copyAs: false, // 复制为
  248. paste: false, // 粘贴
  249. insertRow: false, // 插入行
  250. insertColumn: false, // 插入列
  251. deleteRow: false, // 删除选中行
  252. deleteColumn: false, // 删除选中列
  253. deleteCell: false, // 删除单元格
  254. hideRow: false, // 隐藏选中行和显示选中行
  255. hideColumn: false, // 隐藏选中列和显示选中列
  256. rowHeight: false, // 行高
  257. columnWidth: false, // 列宽
  258. clear: false, // 清除内容
  259. matrix: false, // 矩阵操作选区
  260. sort: false, // 排序选区
  261. filter: false, // 筛选选区
  262. chart: false, // 图表生成
  263. image: false, // 插入图片
  264. link: false, // 插入链接
  265. data: false, // 数据验证
  266. cellFormat: false, // 设置单元格格式
  267. };
  268. };
  269. //请求投标版、签字版psr excel
  270. // const { run: runExcel } = useRequest(queryPsrExcel, {
  271. // manual: true,
  272. // formatResult: (res) => {
  273. // if (res) {
  274. // const jsonData = JSON.parse(res);
  275. // renderSheet(jsonData);
  276. // }
  277. // },
  278. // });
  279. //请求月度psr和现金流列表 data_type 1 psr 2 现金流
  280. const {
  281. // data: historyList,
  282. run: runList,
  283. loading: listLoading,
  284. } = useRequest(
  285. (data) =>
  286. queryPsrMonthList({
  287. project_id: projectId,
  288. data_type: data_type,
  289. ...data,
  290. }),
  291. {
  292. manual: true,
  293. formatResult: (res) => {
  294. if (res.code == 200) {
  295. const list = res?.data?.list?.map((item) => {
  296. let name = dayjs(item.day).format('YYYY-MM');
  297. if (item.ver_type == 1) name = '原始版本';
  298. if (item.ver_type == 2) name = '基础版本';
  299. return { ...item, name };
  300. });
  301. setHistoryList(list);
  302. }
  303. },
  304. },
  305. );
  306. //保存月度psr和现金流接口
  307. const { run: runSave, loading: saveLoading } = useRequest(
  308. (data) => querySavePsrMonth(data),
  309. {
  310. manual: true,
  311. onSuccess: () => {
  312. message.success('保存成功');
  313. },
  314. onError: () => {
  315. message.success('添加失败');
  316. },
  317. },
  318. );
  319. //另存为月度psr和现金流接口
  320. const { run: runSaveOther, loading: saveOtherLoading } = useRequest(
  321. (data) => querySavePsrMonth(data),
  322. {
  323. manual: true,
  324. onSuccess: (data) => {
  325. if (data) {
  326. message.error(data);
  327. return;
  328. }
  329. message.success('另存成功');
  330. if (open) setOpen(false);
  331. //另存成功之后切换到最新的记录
  332. initPsrActrual(key);
  333. },
  334. onError: () => {
  335. message.success('另存失败');
  336. },
  337. },
  338. );
  339. //请求月度psr和现金流详情接口
  340. const { run: runDetail } = useRequest((data) => queryPsrMonthDetail(data), {
  341. manual: true,
  342. formatResult: (res) => {
  343. if (res?.data) {
  344. let data = res.data;
  345. let name = dayjs(data.day).format('YYYY-MM');
  346. if (data.ver_type == 1) name = '原始版本';
  347. if (data.ver_type == 2) name = '基础版本';
  348. setExcelData({ ...data, name });
  349. setHistoryOpen(false);
  350. const jsonData = JSON.parse(data.json_data);
  351. console.log(jsonData);
  352. // if (Array.isArray(data)) {
  353. jsonData.map((item) => {
  354. if (item.celldata && typeof item.celldata == 'string')
  355. item.celldata = JSON.parse(item.celldata);
  356. if (item.config && typeof item.config == 'string')
  357. item.config = JSON.parse(item.config);
  358. });
  359. // } else {
  360. // if (data.celldata) data.celldata = JSON.parse(data.celldata);
  361. // if (data.config) data.config = JSON.parse(data.config);
  362. // }
  363. renderSheet(jsonData, data.is_edit);
  364. // if (jsonData[0].celldata && typeof jsonData[0].celldata == 'string')
  365. // jsonData[0].celldata = JSON.parse(jsonData[0].celldata);
  366. // if (jsonData[0].config && typeof jsonData[0].config == 'string')
  367. // jsonData[0].config = JSON.parse(jsonData[0].config);
  368. // renderSheet(jsonData, data.is_edit);
  369. } else {
  370. setExcelData({ name: '' });
  371. setNoData(true);
  372. }
  373. },
  374. });
  375. //请求签字版PSR历史版本列表
  376. const { run: run, loading: loading } = useRequest(
  377. (id) =>
  378. queryPsrExcelList({
  379. project_id: projectId,
  380. template_node_id: id,
  381. }),
  382. {
  383. manual: true,
  384. formatResult: (res) => {
  385. if (res.code == 200) {
  386. const list = res?.data?.list?.map((item) => {
  387. return { ...item, name: item.version_name };
  388. });
  389. setHistoryList(list);
  390. }
  391. },
  392. },
  393. );
  394. // useEffect(() => {
  395. // let url = '/psrData.json';
  396. // axios.get(url).then((res) => {
  397. // if (res.status == 200) {
  398. // renderSheet(res.data);
  399. // }
  400. // });
  401. // }, [key]);
  402. const data_type = useMemo(() => {
  403. if (key == '3') return 1;
  404. if (key == '4') return 2;
  405. return null;
  406. }, [key]);
  407. useEffect(() => {
  408. let str = '';
  409. switch (key) {
  410. case '2':
  411. str = '签字版PSR_';
  412. break;
  413. case '3':
  414. str = '过程/终版PSR_';
  415. break;
  416. case '4':
  417. str = '现金流_';
  418. break;
  419. }
  420. titleRef.current = str;
  421. setCompareValues([]);
  422. if (key) {
  423. onChange(key);
  424. } else {
  425. queryPsrExcel({ gridKey: node_id });
  426. }
  427. }, [key]);
  428. //请求投标版、签字版psr excel
  429. const queryPsrExcel = (data) => {
  430. axios({
  431. url: `/api/v1/purchase/record/sheet?${stringify(data)}`,
  432. method: 'POST',
  433. data,
  434. headers: {
  435. 'JWT-TOKEN': token,
  436. },
  437. }).then((req) => {
  438. if (req.status == 200) {
  439. const jsonData = JSON.parse(req.data);
  440. renderSheet(jsonData);
  441. }
  442. });
  443. };
  444. const onChange = (key) => {
  445. if (key == '1') {
  446. queryPsrExcel({ gridKey: node_id });
  447. } else if (key == '2') {
  448. queryPsrExcel({ gridKey: flow_id });
  449. } else {
  450. initPsrActrual(key);
  451. }
  452. };
  453. //请求 过程/终版PSR 现金流的数据
  454. const initPsrActrual = async (key) => {
  455. const data_type = key == '3' ? 1 : 2;
  456. const res = await queryPsrMonthLast({ project_id: projectId, data_type });
  457. if (res.data?.length > 0 && res.data[0].json_data) {
  458. let name = `${titleRef.current}${dayjs(res.data[0].day).format(
  459. 'YYYY-MM',
  460. )}`;
  461. if (res.data[0].ver_type == 1) name = '原始版本';
  462. if (res.data[0].ver_type == 2) name = '基础版本';
  463. const isOrigin = res.data[0].ver_type == 1 ? 1 : 0;
  464. setIsOriginVer(isOrigin);
  465. setExcelData({ ...res.data[0], name });
  466. const data = JSON.parse(res.data[0].json_data);
  467. const canEdit = isOrigin ? 0 : res.data[0].is_edit;
  468. if (Array.isArray(data)) {
  469. data.map((item) => {
  470. if (item.celldata && typeof item.celldata == 'string')
  471. item.celldata = JSON.parse(item.celldata);
  472. if (item.config && typeof item.config == 'string')
  473. item.config = JSON.parse(item.config);
  474. });
  475. renderSheet(data, canEdit);
  476. } else {
  477. if (data.celldata) data.celldata = JSON.parse(data.celldata);
  478. if (data.config) data.config = JSON.parse(data.config);
  479. renderSheet([data], canEdit);
  480. }
  481. } else {
  482. setIsOriginVer(false);
  483. setExcelData({ name: '' });
  484. setNoData(true);
  485. }
  486. };
  487. //另存为月版本
  488. const handlerSaveOther = (data) => {
  489. const luckyData = luckysheetRef.current?.toJson();
  490. luckyData?.data.forEach((item) => delete item.data);
  491. //设置表单日期
  492. const date =
  493. data.ver_type == 2 //基础版本是创建当天的日期 月版本是创建月份的最后一天
  494. ? dayjs().format('YYYY-MM-DD')
  495. : dayjs(data.day).endOf('month').format('YYYY-MM-DD');
  496. const days = changeDate(date);
  497. const celldata = luckyData?.data[0]?.celldata;
  498. const rc = key == '3' ? { r: 1, c: 1 } : { r: 1, c: 3 }; //psr日期位置是1 1 现金流日期位置是 1 3
  499. const dateItem = celldata?.find((item) => item.r == rc.r && item.c == rc.c);
  500. if (dateItem) {
  501. dateItem.v.v = days + '';
  502. // dateItem.v.m = days;
  503. }
  504. if (luckyData?.data) {
  505. const params = {
  506. ...data,
  507. project_id: Number(projectId),
  508. json_data: JSON.stringify(luckyData.data),
  509. data_type: data_type,
  510. };
  511. runSaveOther(params);
  512. }
  513. };
  514. //保存
  515. const handlerSave = () => {
  516. const luckyData = luckysheetRef.current?.toJson();
  517. let allData;
  518. //如果是现金流的保存。需要计算一些数值填充到psr中;
  519. if (key == '4') {
  520. //当月发生额数据 计算当月发生额的月份 originC
  521. let newMonthConfig = [...curMonthConfig];
  522. const celldata = luckyData.data[0].celldata;
  523. const originC = getMonthCol(celldata);
  524. if (originC || originC == 0) {
  525. newMonthConfig = curMonthConfig.map((item) => {
  526. return { ...item, originC };
  527. });
  528. }
  529. allData = getPsrDataByAct([...preActConfig, ...newMonthConfig]);
  530. console.log(allData);
  531. }
  532. const params = {
  533. id: excelData?.id,
  534. data_type: excelData?.data_type,
  535. project_id: excelData?.project_id,
  536. day: dayjs(excelData?.day).format('YYYY-MM-DD'),
  537. json_data: JSON.stringify(luckyData.data),
  538. psr_json_data: JSON.stringify(allData),
  539. };
  540. console.log(params);
  541. runSave(params);
  542. };
  543. //获取当月发生额的月份
  544. const getMonthCol = (celldata) => {
  545. //计算出当月发生额的月份 originC
  546. const date = changeDate(excelData?.day); //转换成55078这种格式
  547. const originC = celldata.find(
  548. (item) => item.r == 5 && Math.abs(item.v?.v - date) < 5,
  549. )?.c;
  550. return originC;
  551. };
  552. const getPsrDataByAct = (configList) => {
  553. const luckyData = luckysheetRef.current?.toJson();
  554. let otherValueTotal = 0; //获取除设备费之外的所有费用的和
  555. const preValues = configList.map((item) => {
  556. const celldata = luckyData.data[0].celldata;
  557. const {
  558. type,
  559. originC,
  560. num,
  561. originR: { begin, end },
  562. } = item;
  563. let value = 0;
  564. for (let i = begin; i <= end; i++) {
  565. const item = celldata.find((item) => item.c == originC && item.r == i);
  566. if (item?.v?.v) value += item.v.v;
  567. }
  568. if (type !== ZeroNineType.Equipment) otherValueTotal += value;
  569. return { num, value };
  570. });
  571. const EquPreItem = preValues.find(
  572. (item) => item.type == ZeroNineType.Equipment,
  573. );
  574. if (EquPreItem?.value)
  575. EquPreItem.value = EquPreItem?.value - otherValueTotal; //全部的费用 减去 除设备费之外的所有费用的和 得到设备费
  576. console.log('------预算列的值---------', preValues);
  577. return preValues;
  578. };
  579. const exportExcl = (className) => {
  580. const luckyData = luckysheetRef.current?.toJson();
  581. exportExcel(luckyData.data, className);
  582. };
  583. const handlerLoad = () => {
  584. const contentWindow = iframeRef.current.contentWindow;
  585. luckysheetRef.current = contentWindow.luckysheet;
  586. };
  587. const renderSheet = (currentData, is_edit = false) => {
  588. if (!currentData || !currentData[0]?.celldata) {
  589. setNoData(true);
  590. return;
  591. }
  592. setNoData(false);
  593. if (!luckysheetRef.current) {
  594. setTimeout(() => {
  595. renderSheet(currentData, is_edit);
  596. }, 500);
  597. return;
  598. }
  599. console.log('----------------------', currentData);
  600. const data = currentData;
  601. //设置单元格不可编辑
  602. data?.forEach((item) => {
  603. item.config.authority = is_edit
  604. ? null
  605. : {
  606. sheet: true,
  607. hintText: '当前excel不可编辑!',
  608. };
  609. // 公式计算
  610. let calcChain = [];
  611. let index = item.index;
  612. item.celldata?.forEach((cell) => {
  613. if (typeof cell.v.f !== 'undefined') {
  614. calcChain.push({
  615. r: cell.r,
  616. c: cell.c,
  617. index,
  618. });
  619. }
  620. });
  621. item.calcChain = calcChain;
  622. });
  623. let option = {
  624. lang: 'zh',
  625. showinfobar: false,
  626. showstatisticBar: false,
  627. permissions: user?.Permission,
  628. data: JSON.parse(JSON.stringify(data)),
  629. hook: {
  630. cellMousedown: (cell, position, sheet) => {
  631. console.log(cell, sheet);
  632. },
  633. cellUpdated: () => {
  634. luckysheetRef.current.refreshFormula();
  635. },
  636. workbookCreateAfter: async () => {
  637. setTimeout(() => {
  638. luckysheetRef.current.refreshFormula();
  639. }, 800);
  640. //当前为为终版psr标签并且可编辑状态时填充人日数据
  641. if (key == '3' && is_edit) {
  642. fillWorkLoadData();
  643. // const res = await queryPsrWorkLoad({ project_id: projectId });
  644. // if (res?.data) {
  645. // console.log('--------------------', res.data);
  646. // luckysheetRef.current.setCellValue(8, 4, res.data.Total);
  647. // luckysheetRef.current.setCellValue(8, 8, res.data.Month);
  648. // }
  649. }
  650. },
  651. },
  652. };
  653. option.data.forEach((item) => {
  654. delete item.data;
  655. if (item.celldata) {
  656. item.celldata.forEach((cell) => {
  657. // 生成uuid
  658. if (!cell.v.cid) cell.v.cid = getUUID();
  659. });
  660. }
  661. // 默认禁止编辑
  662. // item.config.authority = { sheet: true, hintText };
  663. });
  664. //设置不可编辑
  665. if (!is_edit) unableEdit(option);
  666. luckysheetRef.current.destroy();
  667. luckysheetRef.current.create(option);
  668. };
  669. const fillWorkLoadData = async () => {
  670. const param = { project_id: projectId };
  671. param.code = workConfig.map((item) => item.code).join(',');
  672. param.s_time = dayjs('2023-01').startOf('month').format('YYYY-MM-DD');
  673. param.e_time = dayjs('2023-07').endOf('month').format('YYYY-MM-DD');
  674. const res = await queryPsrWorkLoad(param);
  675. if (res?.data) {
  676. const data = res?.data; //{ '02-010': [800, 100] };
  677. Object.keys(data).forEach((code) => {
  678. const list = data[code]; //第一个是当月的,第二个是累计的
  679. const fill = workConfig.find((item) => item.code == code)?.fill;
  680. if (list?.length > 0 && fill)
  681. luckysheetRef.current.setCellValue(fill.r, fill.curC, list[0]);
  682. luckysheetRef.current.setCellValue(fill.r, fill.actC, list[1]);
  683. });
  684. console.log('--------------------', res.data);
  685. // luckysheetRef.current.setCellValue(8, 4, res.data.Total);
  686. // luckysheetRef.current.setCellValue(8, 8, res.data.Month);
  687. }
  688. };
  689. const renderTitle = (data_type, name) => {
  690. if (compareValues?.length == 2) {
  691. return (
  692. <div className={styles.exportDiv}>
  693. <Button
  694. type="primary"
  695. onClick={() => {
  696. setCompareValues([]);
  697. setTimeout(() => {
  698. initPsrActrual(key);
  699. }, 500);
  700. }}
  701. >
  702. 退出比对
  703. </Button>
  704. </div>
  705. );
  706. }
  707. if (data_type == 0)
  708. //投标版psr
  709. return (
  710. <div className={styles.exportDiv}>
  711. <Button
  712. type="primary"
  713. onClick={() => exportExcl(name)}
  714. disabled={noData}
  715. >
  716. 导出
  717. </Button>
  718. </div>
  719. );
  720. if (data_type == 3)
  721. //签字版psr
  722. return (
  723. <div className={styles.excelTitle}>
  724. <div style={{ minWidth: '10px' }}>
  725. {/* 当前PSR表单:
  726. <span style={{ color: 'blue' }}>{excelData?.name}</span> */}
  727. </div>
  728. <Space>
  729. <Button
  730. type="primary"
  731. onClick={() => {
  732. run(init_flow_id);
  733. setHistoryOpen(true);
  734. }}
  735. disabled={noData}
  736. >
  737. 历史版本
  738. </Button>
  739. <Button
  740. type="primary"
  741. onClick={() => exportExcl(name)}
  742. disabled={noData}
  743. >
  744. 导出
  745. </Button>
  746. </Space>
  747. </div>
  748. );
  749. //过程/终版psr 现金流
  750. return (
  751. <div className={styles.excelTitle}>
  752. <div>
  753. 当前{key == '4' ? '现金流' : 'PSR'}表单:
  754. <span style={{ color: 'blue' }}>{excelData?.name}</span>
  755. </div>
  756. <Space>
  757. <Button
  758. type="primary"
  759. onClick={() => {
  760. runList();
  761. setHistoryOpen(true);
  762. }}
  763. disabled={noData}
  764. >
  765. 历史版本
  766. </Button>
  767. <Button
  768. type="primary"
  769. onClick={() => setOpen(true)}
  770. disabled={!excelData?.is_edit}
  771. >
  772. 另存为
  773. </Button>
  774. <Button
  775. type="primary"
  776. onClick={handlerSave}
  777. loading={saveLoading}
  778. disabled={!excelData?.is_edit || isOriginVer}
  779. >
  780. 保存
  781. </Button>
  782. <Button
  783. type="primary"
  784. onClick={() => setCompareOpen(true)}
  785. disabled={noData}
  786. >
  787. 比对
  788. </Button>
  789. <Button
  790. type="primary"
  791. onClick={() => exportExcl(excelData?.name)}
  792. disabled={noData}
  793. >
  794. 导出
  795. </Button>
  796. </Space>
  797. </div>
  798. );
  799. };
  800. const changeDate = (date) => {
  801. date = dayjs(date);
  802. const startDate = dayjs('1900-01-01');
  803. const daysDifference = date.diff(startDate, 'day');
  804. return daysDifference;
  805. };
  806. const items = [
  807. {
  808. key: '1',
  809. label: '投标版PSR',
  810. children: renderTitle(0, '投标版PSR'),
  811. },
  812. {
  813. key: '2',
  814. label: '签字版PSR',
  815. children: renderTitle(3, '签字版PSR'),
  816. },
  817. {
  818. key: '3',
  819. label: '过程/终版PSR',
  820. children: renderTitle(1, '过程/终版PSR'),
  821. },
  822. {
  823. key: '4',
  824. label: '现金流',
  825. children: renderTitle(2, '现金流'),
  826. },
  827. ];
  828. // const handlerOnChange = (event) => {
  829. // console.log(event);
  830. // console.log('----------------', luckysheetRef.current);
  831. // var file = event.target.files[0];
  832. // var fileName = file.name;
  833. // fileName = fileName + '';
  834. // //將文件加載到頁面上
  835. // LuckyExcel.transformExcelToLucky(
  836. // file,
  837. // function (exportJson, luckysheetfile) {
  838. // if (exportJson.sheets == null || exportJson.sheets.length == 0) {
  839. // alert(
  840. // 'Failed to read the content of the excel file, currently does not support xls files!',
  841. // );
  842. // return;
  843. // }
  844. // console.log(exportJson, luckysheetfile);
  845. // renderSheet(exportJson?.sheets);
  846. // // window.luckysheet.destroy();
  847. // // window.luckysheet.create({
  848. // // container: 'luckysheet', //luckysheet is the container id
  849. // // showinfobar:false,
  850. // // lang: 'zh', // 设定表格语言
  851. // // allowEdit: true,//作用:是否允许前台编辑
  852. // // // allowUpdate: true,
  853. // // allowCopy: true, //是否允许拷贝
  854. // // showtoolbar: true, //是否第二列显示工具栏
  855. // // showinfobar: true, //是否显示顶部名称栏
  856. // // showsheetbar: true, //是否显示底部表格名称区域
  857. // // showstatisticBar: true, //是否显示底部计数栏
  858. // // pointEdit: false, //是否是编辑器插入表格模式
  859. // // pointEditUpdate: null, //编辑器表格更新函数
  860. // // data:exportJson.sheets,
  861. // // title:exportJson.info.name,
  862. // // userInfo:exportJson.info.name.creator,
  863. // // functionButton: '<button id="" class="btn btn-primary" style=" padding:3px 6px; font-size: 16px;width: 100px;height: 27px; margin-right: 85px;" οnclick="downExcelData()">導出</button>',
  864. // // });
  865. // },
  866. // );
  867. // };
  868. const handlerDetailClick = (id) => {
  869. if (key == '2') {
  870. queryPsrExcel({ gridKey: id });
  871. setHistoryOpen(false);
  872. return;
  873. }
  874. runDetail({ id });
  875. };
  876. return (
  877. <PageContent>
  878. <div className={styles.titleDev}>
  879. <Button type="primary" onClick={() => navigate(-1)}>
  880. 返回
  881. </Button>
  882. {/* <input type="file" onChange={handlerOnChange} /> */}
  883. <span className={styles.title}>{project_name}</span>
  884. </div>
  885. <Tabs
  886. defaultActiveKey="1"
  887. type="card"
  888. items={items}
  889. onChange={(key) => {
  890. setKey(key);
  891. titleRef.current = '';
  892. }}
  893. />
  894. {noData && <div className={styles.noData}>暂无数据</div>}
  895. {compareValues?.length == 2 ? (
  896. <CompareCom values={compareValues} />
  897. ) : (
  898. <iframe
  899. style={{
  900. width: '100%',
  901. height: '80vh',
  902. overflowX: 'hidden',
  903. display: noData ? 'none' : 'block',
  904. }}
  905. ref={iframeRef}
  906. onLoad={handlerLoad}
  907. src="/luckysheet.html"
  908. />
  909. )}
  910. <Drawer
  911. title="历史版本"
  912. placement="right"
  913. loading={listLoading}
  914. onClose={() => setHistoryOpen(false)}
  915. open={historyOpen}
  916. >
  917. <Timeline
  918. items={historyList?.map((item) => {
  919. return {
  920. children: (
  921. <a onClick={() => handlerDetailClick(item.id)}>
  922. {titleRef.current}
  923. {item.name}
  924. </a>
  925. ),
  926. };
  927. })}
  928. />
  929. </Drawer>
  930. <SaveModal
  931. showType={key == '4'}
  932. loading={saveOtherLoading}
  933. open={open}
  934. onCancel={() => setOpen(false)}
  935. onOk={handlerSaveOther}
  936. />
  937. <CompareModal
  938. list={historyList}
  939. open={compareOpen}
  940. onOk={(values) => {
  941. setCompareValues(values);
  942. setCompareOpen(false);
  943. }}
  944. onCancel={() => setCompareOpen(false)}
  945. />
  946. </PageContent>
  947. );
  948. };
  949. export default PSRDetail;