detail.js 7.9 KB

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