Procházet zdrojové kódy

Squashed commit of the following:
导出/权限
commit 328cee4168f973027056acba285f8c1f1708becd
Author: Renxy <18510891294@163.com>
Date: Tue Oct 24 15:51:24 2023 +0800

记录下载记录

commit 00f38e533c40cf8a178ebbe0fb4e96353f7d3b99
Author: Renxy <18510891294@163.com>
Date: Fri Oct 20 18:01:01 2023 +0800

update

commit b4c336d1e61354360528db701eeb626dbfd3621b
Author: Renxy <18510891294@163.com>
Date: Fri Oct 20 16:53:21 2023 +0800

优化导出图片加水印

commit 40f4a76196ab370e2cb6c4bdab54f70ff68a9b62
Author: Renxy <18510891294@163.com>
Date: Fri Oct 20 10:12:31 2023 +0800

优化导出加水印

commit a3c3bddbd2f4d6e4527a7ff8d5a322a31c1dd74e
Author: Renxy <18510891294@163.com>
Date: Thu Oct 19 20:02:07 2023 +0800

update

commit 2be4cc1ccf49be93fcf2df536010f4954fbbf4e8
Author: Renxy <18510891294@163.com>
Date: Thu Oct 19 19:59:37 2023 +0800

图片加水印/节点加类型

Renxy před 1 rokem
rodič
revize
380e9c0d4b

+ 22 - 1
src/components/Flow/node/circle/mapServe.tsx

@@ -21,12 +21,16 @@ export interface IConfig {
   flow_id?: string;
   flow_node_id?: string;
   process_code?: string;
+  node_type_psr?: number | string;
 }
-
+const defaultConfig: IConfig = {
+  node_type_psr: 0,
+};
 const Component = (props: any) => {
   const { config, plugin = {}, auditList } = props;
   const { updateNode } = plugin;
   const [nodeConfig, setNodeConfig] = useState<IConfig>({
+    ...defaultConfig,
     ...config,
   });
   const app = useXFlowApp();
@@ -102,6 +106,23 @@ const Component = (props: any) => {
             };
           })}
         />
+        <SelectField
+          label="节点类型"
+          value={nodeConfig.node_type_psr}
+          onChange={value => {
+            onNodeConfigChange('node_type_psr', value);
+          }}
+          options={[
+            { label: '默认', value: 0 },
+            { label: '投标版', value: 1 },
+            { label: '签字版', value: 2 },
+            { label: '投标测算', value: 3 },
+            { label: '合同测算', value: 4 },
+            { label: '采购合同', value: 5 },
+            { label: '方案总审', value: 6 },
+            { label: '清单权限', value: 7 }, //发起人和审批人可见
+          ]}
+        />
       </div>
 
       {meta?.editMode != 2 && (

+ 2 - 0
src/components/Flow/node/rect/mapServe.tsx

@@ -242,6 +242,8 @@ const Component = (props: any) => {
             { label: '投标测算', value: 3 },
             { label: '合同测算', value: 4 },
             { label: '采购合同', value: 5 },
+            { label: '方案总审', value: 6 },
+            { label: '清单权限', value: 7 }, //发起人和审批人可见
           ]}
         />
         {nodeConfig.is_start_node == 1 && (

+ 13 - 9
src/pages/Detail/DropdownMenu.js

@@ -84,8 +84,8 @@ function DropdownMenu(props) {
           cancelText: '取消',
           onOk: async () => {
             await setLastVersion(version.id);
-            version.last_version = 1
-            setVersion(version)
+            version.last_version = 1;
+            setVersion(version);
             localStorage.excelItem = JSON.stringify(version);
           },
         });
@@ -110,7 +110,9 @@ function DropdownMenu(props) {
         </>
       );
     } else {
-      return <Button onClick={() => onClick({ key: 'closeCompare', data: true })}>取消比对</Button>;
+      return (
+        <Button onClick={() => onClick({ key: 'closeCompare', data: false })}>取消比对</Button>
+      );
     }
   }
 
@@ -136,17 +138,20 @@ function DropdownMenu(props) {
           .some(id => currentUser.roleList?.find(role => role.ID == id));
       }
       // 没有分类的不设置权限
-      if(version.classify_id === 0) return true;
+      if (version.classify_id === 0) return true;
       // 非全部分类判断是否含有权限
-      if(version.classify_id != 1) {
+      if (version.classify_id != 1) {
         // 判断在特定分类下是否有权限
         const uidsStr = classifyList.find(item => item.classify_id == version.classify_id)?.uid;
         if (uidsStr && uidsStr.split(',')?.findIndex(item => item == currentUser.ID) < 0) {
           bool = false;
-          
+
           // 判断在全部分类下是否有权限
-          const allUidsStr = classifyList.find(item => item.classify_id == 1)?.uid
-          if (allUidsStr && allUidsStr.split(',')?.findIndex(item => item == currentUser.ID) != -1) {
+          const allUidsStr = classifyList.find(item => item.classify_id == 1)?.uid;
+          if (
+            allUidsStr &&
+            allUidsStr.split(',')?.findIndex(item => item == currentUser.ID) != -1
+          ) {
             bool = true;
           }
         }
@@ -158,7 +163,6 @@ function DropdownMenu(props) {
 
     if (!isAuditor && canEdit() && !version.flow_id) {
       menuList.push(<Menu.Item key="merge">同步</Menu.Item>);
-     
     }
   }
   if (!isLastVersion) menuList.push(<Menu.Item key="lastVersion">设为最终版本</Menu.Item>);

+ 35 - 21
src/pages/Detail/Index.js

@@ -22,6 +22,7 @@ import {
   queryDelSheetRecord,
   queryDetail,
   queryDingInstanceExecute,
+  queryDownloadLogCreate,
   setLastVersion,
 } from '@/services/boom';
 import HistoryDrawer from './HistoryDrawer';
@@ -35,6 +36,7 @@ import DropdownMenu from './DropdownMenu';
 import CurrentInfo from './CurrentInfo';
 import moment from 'moment';
 import PsrControl from './PsrControl';
+import exportExcelImg from './exportExcelImg';
 
 function Detail(props) {
   const {
@@ -249,24 +251,26 @@ function Detail(props) {
   };
   // 更新表单,flag为true时不判断是否属于审批,强制更新
   const onUpdate = flag => {
-    if (!flag && flow.active != 0) return;
-    let currentData = sheetRef.current.getSheetJson().data;
-    let sheets = JSON.parse(JSON.stringify(currentData));
-    sheets.forEach(item => {
-      delete item.data;
-    });
-    let params = {
-      ...version,
-      data: JSON.stringify(sheets),
-    };
+    // if (!flag && flow.active != 0) return;
+    if (node?.node_type_psr == 6 || flag || flow.active == 0) {
+      let currentData = sheetRef.current.getSheetJson().data;
+      let sheets = JSON.parse(JSON.stringify(currentData));
+      sheets.forEach(item => {
+        delete item.data;
+      });
+      let params = {
+        ...version,
+        data: JSON.stringify(sheets),
+      };
 
-    dispatch({
-      type: 'detail/saveSheet',
-      payload: params,
-      callback: () => {
-        setSaveTime(moment().format('HH:mm:ss'));
-      },
-    });
+      dispatch({
+        type: 'detail/saveSheet',
+        payload: params,
+        callback: () => {
+          setSaveTime(moment().format('HH:mm:ss'));
+        },
+      });
+    }
   };
 
   const onDelSheet = async id => {
@@ -373,7 +377,7 @@ function Detail(props) {
         // 同步清单
         setMergeVisible(true);
         break;
-      case 'compare':
+      case 'closeCompare':
         // 同步
         onCompare(e.data);
         break;
@@ -532,7 +536,6 @@ function Detail(props) {
   }, [compareList]);
 
   useEffect(() => {
-    // if (versionList.length == 0) return;
     if (!currentUser.ID) return;
     if (!version.id) {
       changeVersion(excelID);
@@ -564,12 +567,23 @@ function Detail(props) {
               保存
             </Button>
           )}
+          <Button type="primary" onClick={() => setVersionTreeVisible(true)}>
+            历史版本
+          </Button>
           <Button
             type="primary"
             style={{ marginRight: 20 }}
-            onClick={() => setVersionTreeVisible(true)}
+            onClick={() => {
+              queryDownloadLogCreate({
+                excel_id: version.id,
+                node_id: version.template_node_id,
+                url: '',
+              });
+              const src = sheetRef.current?.luckysheet.getScreenshot();
+              exportExcelImg(src, currentUser?.CName);
+            }}
           >
-            历史版本
+            导出图片
           </Button>
           <Avatar.Group style={{ marginRight: 20 }}>
             {user.map((item, id) => (

+ 10 - 8
src/pages/Detail/LuckySheet.js

@@ -214,7 +214,7 @@ class LuckySheet extends React.Component {
         };
       };
 
-      if (version.flow_id) {
+      if (version.flow_id && node?.node_type_psr != 6) {
         option.authority = {
           sheet: true,
           hintText: '当前处于审批节点,禁止编辑!',
@@ -226,13 +226,16 @@ class LuckySheet extends React.Component {
           hintText: '该清单已设置为最终版本,禁止编辑!',
         };
         unableEdit(option);
-      } else if ((version.audit_status != 0 && version.audit_status != 5) || version.status == 1) {
+      } else if (
+        node?.node_type_psr != 6 &&
+        ((version.audit_status != 0 && version.audit_status != 5) || version.status == 1)
+      ) {
         option.authority = {
           sheet: true,
           hintText: '当前清单不可编辑!',
         };
         unableEdit(option);
-      } else if (node?.node_type_psr == 1 ||node?.node_type_psr == 2 || node?.node_type_psr == 5 ) {
+      } else if (node?.node_type_psr == 1 || node?.node_type_psr == 2 || node?.node_type_psr == 5) {
         option.authority = {
           sheet: true,
           hintText: '流程已完结,不可编辑!',
@@ -272,7 +275,6 @@ class LuckySheet extends React.Component {
       this.luckysheet.setCellFormat(0, 0, 'bg', '#fff');
       this.luckysheet.refreshFormula();
     }, 500);
-    
   }
 
   // componentDidUpdate(prevProps) {
@@ -662,11 +664,11 @@ class LuckySheet extends React.Component {
       luckysheet.setCellValue(9, 2, result, {
         order,
       });
-      console.log(result)
-      luckysheet.refreshFormula()
-      message.success("计算成功")
+      console.log(result);
+      luckysheet.refreshFormula();
+      message.success('计算成功');
     } catch (error) {
-      message.error("计算失败")
+      message.error('计算失败');
       console.log(error);
     }
   }

+ 86 - 0
src/pages/Detail/exportExcelImg.js

@@ -0,0 +1,86 @@
+import { downloadFile } from '@/utils/utils';
+import { async } from '@antv/x6/lib/registry/marker/async';
+
+function blobToImg(blob) {
+  return new Promise((resolve, reject) => {
+    let reader = new FileReader();
+    reader.addEventListener('load', () => {
+      let img = new Image();
+      img.src = reader.result;
+      img.addEventListener('load', () => resolve(img));
+    });
+    reader.readAsDataURL(blob);
+  });
+}
+
+async function imgToCanvas(data64) {
+  let canvas = document.createElement('canvas');
+  let ctx = canvas.getContext('2d');
+  return new Promise((resolve, reject) => {
+    let img = new Image();
+    img.src = data64;
+    img.onload = () => {
+      canvas.width = img.width;
+      canvas.height = img.height;
+      ctx.drawImage(img, 0, 0);
+      resolve(canvas);
+    };
+  });
+}
+
+async function textToCanvas(text) {
+  let canvas = document.createElement('canvas');
+  let ctx = canvas.getContext('2d');
+  canvas.width = 200;
+  canvas.height = 200;
+
+  return new Promise((resolve, reject) => {
+    // 设置填充字号和字体,样式
+    ctx.font = '24px 宋体';
+    ctx.fillStyle = '#92dfff';
+    // 设置右对齐
+    ctx.textAlign = 'center';
+    ctx.save();
+    ctx.translate(100, 100);
+    ctx.rotate((45 * Math.PI) / 180);
+    ctx.fillText(text, 0, 0);
+    canvas.toBlob(blob => {
+      resolve(blob);
+    });
+  });
+}
+
+async function textBlobToCanvas(canvas, textBlob) {
+  let ctx = canvas.getContext('2d');
+  return new Promise((resolve, reject) => {
+    let img = new Image();
+    const url = URL.createObjectURL(textBlob);
+    img.src = url;
+    img.onload = () => {
+      const row = canvas.width / img.width;
+      const col = canvas.height / img.height;
+      for (let i = 0; i < row; i++) {
+        for (let j = 0; j < col; j++) {
+          ctx.drawImage(img, i * 200, j * 200, 200, 200);
+        }
+      }
+      canvas.toBlob(blob => {
+        console.log(blob);
+        resolve(blob);
+      });
+    };
+  });
+}
+
+export default async function(data64, text = '金科环境') {
+  //获取text绘制到画布,获取blob信息
+  const textBlob = await textToCanvas(text);
+  //excel内容绘制到画布
+  let canvas = await imgToCanvas(data64);
+  //将textBlob平铺到画布上
+  let blob = await textBlobToCanvas(canvas, textBlob);
+
+  // let newImage = await blobToImg(blob);
+  const url = URL.createObjectURL(blob);
+  downloadFile(url, 'excel');
+}

+ 8 - 3
src/services/boom.js

@@ -506,8 +506,13 @@ export async function getAuditDetail(params) {
   return res.data;
 }
 export async function getVersionDetail(params) {
-  const res = await request(
-    `/api/v1/purchase/bom/get-excel-detail?excel_id=${params.excelID}`
-  );
+  const res = await request(`/api/v1/purchase/bom/get-excel-detail?excel_id=${params.excelID}`);
   return res.data;
 }
+//下载excel表单 需要记录下载记录 excel_id  node_id  url
+export async function queryDownloadLogCreate(data) {
+  return request(`/api/v1/purchase/download-log/create`, {
+    method: 'POST',
+    body: data,
+  });
+}