detail.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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, useRef, useState } from 'react';
  5. import axios from 'axios';
  6. import {
  7. useLocation,
  8. useParams,
  9. useRequest,
  10. useSearchParams,
  11. } from '@umijs/max';
  12. import {
  13. queryPsrExcel,
  14. queryPsrMonthDetail,
  15. queryPsrMonthList,
  16. queryPsrWorkLoad,
  17. querySavePsrMonth,
  18. } from '../../services/psr';
  19. import SaveModal from './components/saveOtherModal';
  20. import dayjs from 'dayjs';
  21. const PSRDetail = () => {
  22. const params = useParams();
  23. const location = useLocation();
  24. const { id: projectId } = params;
  25. const {
  26. state: { project_name, flow_id, node_id },
  27. } = location;
  28. console.log('========================', location, luckysheet);
  29. const [excelData, setExcelData] = useState();
  30. const [historyOpen, setHistoryOpen] = useState();
  31. const [open, setOpen] = useState();
  32. const [dataType, setDataType] = useState();
  33. const luckysheetRef = useRef();
  34. const iframeRef = useRef();
  35. const unableEdit = (option) => {
  36. option.showtoolbar = false;
  37. option.enableAddRow = false;
  38. option.sheetFormulaBar = false;
  39. option.enableAddBackTop = false;
  40. option.showsheetbarConfig = {
  41. add: false,
  42. sheet: false,
  43. };
  44. option.cellRightClickConfig = {
  45. copy: false, // 复制
  46. copyAs: false, // 复制为
  47. paste: false, // 粘贴
  48. insertRow: false, // 插入行
  49. insertColumn: false, // 插入列
  50. deleteRow: false, // 删除选中行
  51. deleteColumn: false, // 删除选中列
  52. deleteCell: false, // 删除单元格
  53. hideRow: false, // 隐藏选中行和显示选中行
  54. hideColumn: false, // 隐藏选中列和显示选中列
  55. rowHeight: false, // 行高
  56. columnWidth: false, // 列宽
  57. clear: false, // 清除内容
  58. matrix: false, // 矩阵操作选区
  59. sort: false, // 排序选区
  60. filter: false, // 筛选选区
  61. chart: false, // 图表生成
  62. image: false, // 插入图片
  63. link: false, // 插入链接
  64. data: false, // 数据验证
  65. cellFormat: false, // 设置单元格格式
  66. };
  67. };
  68. //请求投标版、签字版psr excel
  69. const { run: runExcel } = useRequest(queryPsrExcel, {
  70. manual: true,
  71. formatResult: (res) => {
  72. if (res) {
  73. const jsonData = JSON.parse(res);
  74. renderSheet(jsonData);
  75. }
  76. },
  77. });
  78. //请求月度psr和现金流列表 data_type 1 psr 2 现金流
  79. const {
  80. data,
  81. run: runList,
  82. loading: listLoading,
  83. } = useRequest(
  84. (data) =>
  85. queryPsrMonthList({
  86. project_id: projectId,
  87. data_type: dataType,
  88. ...data,
  89. }),
  90. { manual: true },
  91. );
  92. //保存/另存为月度psr和现金流接口
  93. const { run: runSave, loading: saveLoading } = useRequest(
  94. (data) => querySavePsrMonth(data),
  95. {
  96. manual: true,
  97. onSuccess: () => {
  98. message.success('保存成功');
  99. if (open) setOpen(false);
  100. },
  101. onError: () => {
  102. message.success('添加失败');
  103. },
  104. },
  105. );
  106. //请求月度psr和现金流详情接口
  107. const { run: runDetail } = useRequest((data) => queryPsrMonthDetail(data), {
  108. manual: true,
  109. formatResult: (res) => {
  110. if (res?.data) {
  111. let data = res.data;
  112. console.log(data);
  113. const day = dayjs(data.day).format('YYYY-MM');
  114. setExcelData({ ...data, dayFormat: day });
  115. setHistoryOpen(false);
  116. const jsonData = JSON.parse(data.json_data);
  117. renderSheet(jsonData, data.is_edit);
  118. if (data.is_edit) runWorkLoad({ project_id: projectId });
  119. }
  120. },
  121. });
  122. //请求人日有效工时
  123. const { data: workData, run: runWorkLoad } = useRequest(
  124. (data) => queryPsrWorkLoad(data),
  125. {
  126. manual: true,
  127. },
  128. );
  129. const onChange = (key) => {
  130. if (key == '3' || key == '4') {
  131. const data_type = key == '3' ? 1 : 2;
  132. setDataType(data_type);
  133. runList({ data_type });
  134. axios.get('/excelData.json').then((res) => {
  135. if (res.status == 200) {
  136. renderSheet(res.data);
  137. }
  138. });
  139. } else if (key == '1') {
  140. runExcel({ gridKey: node_id });
  141. } else {
  142. runExcel({ gridKey: flow_id });
  143. }
  144. };
  145. useEffect(() => {
  146. runExcel({ gridKey: node_id });
  147. // axios.get('/excelData.json').then((res) => {
  148. // if (res.status == 200) {
  149. // renderSheet(res.data);
  150. // }
  151. // });
  152. // setTimeout(() => {
  153. // luckysheetRef.current.setCellValue(1, 1, 33333);
  154. // }, 5000);
  155. }, []);
  156. const handlerSaveOther = (date) => {
  157. const luckyData = luckysheetRef.current?.toJson();
  158. if (luckyData?.data) {
  159. console.log('========================', luckyData);
  160. const params = {
  161. day: date,
  162. project_id: projectId,
  163. json_data: JSON.stringify(luckyData.data),
  164. data_type: dataType,
  165. };
  166. runSave(params);
  167. }
  168. };
  169. const handlerSave = () => {
  170. const luckyData = luckysheetRef.current?.toJson();
  171. const params = {
  172. id: excelData?.id,
  173. data_type: excelData?.data_type,
  174. project_id: excelData?.project_id,
  175. day: dayjs(excelData?.day).format('YYYY-MM-DD'),
  176. json_data: JSON.stringify(luckyData.data),
  177. };
  178. runSave(params);
  179. };
  180. const renderSheet = (currentData, is_edit = false) => {
  181. const data = currentData;
  182. //设置单元格不可编辑
  183. data?.forEach((item) => {
  184. item.config.authority = is_edit
  185. ? null
  186. : {
  187. sheet: true,
  188. hintText: '当前excel不可编辑!',
  189. };
  190. });
  191. console.log(data);
  192. let option = {
  193. lang: 'zh',
  194. showinfobar: false,
  195. showstatisticBar: false,
  196. data: JSON.parse(JSON.stringify(data)),
  197. hook: {
  198. cellMousedown: (cell, position, sheet) => {
  199. console.log(cell, position, sheet);
  200. },
  201. cellUpdated: () => {
  202. luckysheetRef.current.refreshFormula();
  203. },
  204. workbookCreateAfter: () => {},
  205. },
  206. };
  207. //设置不可编辑
  208. if (!is_edit) unableEdit(option);
  209. luckysheetRef.current.destroy();
  210. luckysheetRef.current.create(option);
  211. };
  212. const renderTitle = (data_type) => {
  213. const title = data_type == 1 ? 'PSR' : '现金流';
  214. return (
  215. <div className={styles.excelTitle}>
  216. <div>
  217. 当前PSR表单:
  218. <span style={{ color: 'blue' }}>{excelData?.dayFormat}</span>
  219. </div>
  220. <Space>
  221. <Button
  222. type="primary"
  223. onClick={() => {
  224. runList();
  225. setHistoryOpen(true);
  226. }}
  227. >
  228. {`${title}历史版本`}
  229. </Button>
  230. <Button
  231. type="primary"
  232. onClick={() => setOpen(true)}
  233. disabled={!excelData?.is_edit}
  234. >
  235. 另存为
  236. </Button>
  237. {/* <Button type="primary">编辑</Button> */}
  238. <Button
  239. type="primary"
  240. onClick={handlerSave}
  241. disabled={!excelData?.is_edit}
  242. >
  243. 保存
  244. </Button>
  245. </Space>
  246. </div>
  247. );
  248. };
  249. const handlerLoad = () => {
  250. const contentWindow = iframeRef.current.contentWindow;
  251. luckysheetRef.current = contentWindow.luckysheet;
  252. };
  253. const items = [
  254. {
  255. key: '1',
  256. label: '投标版PSR',
  257. // children: `Content of Tab Pane 1`,
  258. },
  259. {
  260. key: '2',
  261. label: '签字版PSR',
  262. // children: `Content of Tab Pane 2`,
  263. },
  264. {
  265. key: '3',
  266. label: '终版PSR',
  267. children: renderTitle(1),
  268. },
  269. {
  270. key: '4',
  271. label: '现金流',
  272. children: renderTitle(2),
  273. },
  274. ];
  275. return (
  276. <PageContent>
  277. <div className={styles.titleDev}>
  278. <Button type="primary">返回</Button>
  279. <span className={styles.title}>{project_name}</span>
  280. </div>
  281. <Tabs
  282. defaultActiveKey="1"
  283. type="card"
  284. items={items}
  285. onChange={onChange}
  286. />
  287. <iframe
  288. style={{
  289. width: '100%',
  290. height: '80vh',
  291. }}
  292. ref={iframeRef}
  293. onLoad={handlerLoad}
  294. src="/luckysheet.html"
  295. />
  296. <Drawer
  297. title="历史版本"
  298. placement="right"
  299. loading={listLoading}
  300. onClose={() => setHistoryOpen(false)}
  301. open={historyOpen}
  302. >
  303. <Timeline
  304. items={data?.list?.map((item) => {
  305. return {
  306. children: (
  307. <a onClick={() => runDetail({ id: item.id })}>
  308. {dayjs(item.day).format('YYYY-MM')}
  309. </a>
  310. ),
  311. };
  312. })}
  313. />
  314. </Drawer>
  315. <SaveModal
  316. loading={saveLoading}
  317. open={open}
  318. onCancel={() => setOpen(false)}
  319. onOk={handlerSaveOther}
  320. />
  321. </PageContent>
  322. );
  323. };
  324. export default PSRDetail;