ソースを参照

报表数据映射-界面功能提交

lxh 8 ヶ月 前
コミット
229d870ec6

+ 21 - 20
src/views/vent/monitorManager/alarmMonitor/common/closeWall.vue

@@ -85,7 +85,9 @@
       <div class="echart-box">
         <div class="left-echartbox">
           <div class="title-f">
-            <div class="title-text">{{ `${type}趋势` }}</div>
+            <div class="title-text">{{ `${type}趋势` }}&nbsp; <span style="color: red">{{ posMonitor['netStatus'] != 1 ?
+              '(设备未连接)' :
+                '' }}</span></div>
           </div>
           <div class="echarts-box">
             <echartLine1 :echartDataSg="echartDataSg1" :lengedDataName="echartDataSg1.lengedDataName" />
@@ -109,7 +111,6 @@ import warnZb from './warnZb.vue'
 let props = defineProps({
   listData: Object,
 });
-
 let widthV = ref('75%')
 let heightV = ref('80%')
 let coordDw = ref<any[]>([26, 46, 80, 128, 190, 260,])
@@ -424,30 +425,30 @@ watch(
             margin-left: 10px;
           }
         }
-        
+
         .value1 {
-         color: rgb(145, 230, 9) !important;
-       }
+          color: rgb(145, 230, 9) !important;
+        }
 
-       .value2 {
-         color: rgb(0, 242, 255) !important;
-       }
+        .value2 {
+          color: rgb(0, 242, 255) !important;
+        }
 
-       .value3 {
-         color: #ffff35 !important;
-       }
+        .value3 {
+          color: #ffff35 !important;
+        }
 
-       .value4 {
-         color: #ffbe69 !important;
-       }
+        .value4 {
+          color: #ffbe69 !important;
+        }
 
-       .value5 {
-         color: #ff6f00 !important;
-       }
+        .value5 {
+          color: #ff6f00 !important;
+        }
 
-       .value6 {
-         color: #ff0000 !important;
-       }
+        .value6 {
+          color: #ff0000 !important;
+        }
       }
     }
   }

+ 276 - 284
src/views/vent/performance/fileDetail/commen/treeList.vue

@@ -1,17 +1,7 @@
 <template>
   <div class="vtl-node" :id="model.id" :class="{ 'vtl-leaf-node': !isFolder, 'vtl-tree-node': isFolder }">
-    <div
-      :class="treeNodeClass"
-      :draggable="draggable"
-      @dragover="dragOver"
-      @drop="drop"
-      @dragstart="dragStart"
-      @mouseover="mouseOver"
-      @dragenter="dragEnter"
-      @dragleave="dragLeave"
-      @mouseout="mouseOut"
-      @click.stop="toggle"
-    >
+    <div :class="treeNodeClass" :draggable="draggable" @dragover="dragOver" @drop="drop" @dragstart="dragStart"
+      @mouseover="mouseOver" @dragenter="dragEnter" @dragleave="dragLeave" @mouseout="mouseOut" @click.stop="toggle">
       <div class="vtl-border-text">
         <template v-if="isFolder">
           <slot v-if="expanded" :item="{ title: model.title, isFolder: true, expanded: true }" name="icon"> </slot>
@@ -21,7 +11,8 @@
         <span class="vtl-node-content ellipsis" v-if="!editable && !model.isAdd">
           {{ model.title }}
         </span>
-        <input v-else class="vtl-input" type="text" ref="nodeInput" v-model="model.title" @keyup.enter.native="setUnEditable" @blur="setUnEditable" />
+        <input v-else class="vtl-input" type="text" ref="nodeInput" v-model="model.title"
+          @keyup.enter.native="setUnEditable" @blur="setUnEditable" />
       </div>
       <div class="vtl-operation" v-show="isHover && !editable && !model.isAdd">
         <!-- <span @click.stop.prevent="addChildFolder" v-if="isFolder">
@@ -36,27 +27,20 @@
         <span @click.stop.prevent="delNode">
           <slot name="operation" type="deleteNode"></slot>
         </span>
+        <span @click.stop.prevent="downNode" v-if="isFolder">
+          <slot name="operation" type="downloadNode"></slot>
+        </span>
       </div>
     </div>
   </div>
   <div class="vtl-tree-margin" v-show="expanded" v-if="isFolder">
     <!-- 这里无法使用$attr来透传属性官方还未解决此bug -->
-    <treeList
-      @on-click="(depth) => $emit('onClick', depth)"
-      @change-name="(depth) => $emit('changeName', depth)"
-      @delete-node="(depth) => $emit('deleteNode', depth)"
-      @add-node="(depth) => $emit('addNode', depth)"
-      @on-drop="(depth) => $emit('onDrop', depth)"
-      @add-folder="(depth) => $emit('addFolder', depth)"
-      @dragStart="(depth) => $emit('dragStart', depth)"
-      @setDragEnterNode="setDragEnterNode"
-      @setDragFile="setDragFile"
-      @setDragFolder="setDragFolder"
-      v-for="newmodel in model.children"
-      :selected="selected"
-      :model="newmodel"
-      :key="newmodel.id"
-    >
+    <treeList @on-click="(depth) => $emit('onClick', depth)" @change-name="(depth) => $emit('changeName', depth)"
+      @delete-node="(depth) => $emit('deleteNode', depth)" @download-node="(depth) => $emit('downloadNode', depth)"
+      @add-node="(depth) => $emit('addNode', depth)" @on-drop="(depth) => $emit('onDrop', depth)"
+      @add-folder="(depth) => $emit('addFolder', depth)" @dragStart="(depth) => $emit('dragStart', depth)"
+      @setDragEnterNode="setDragEnterNode" @setDragFile="setDragFile" @setDragFolder="setDragFolder"
+      v-for="newmodel in model.children" :selected="selected" :model="newmodel" :key="newmodel.id">
       <template #icon="slotProps">
         <slot name="icon" v-bind="slotProps"></slot>
       </template>
@@ -67,294 +51,302 @@
   </div>
 </template>
 <script setup lang="ts">
-  import { computed, ref, watchEffect } from 'vue';
-  interface IFileSystem {
-    id: string;
-    title: string;
-    pid: string;
-    isFolder: boolean;
-    isAdd: boolean;
-    children?: IFileSystem[];
+import { computed, ref, watchEffect } from 'vue';
+interface IFileSystem {
+  id: string;
+  title: string;
+  pid: string;
+  isFolder: boolean;
+  isAdd: boolean;
+  children?: IFileSystem[];
+}
+// 吐出去的事件
+const emit = defineEmits([
+  'onClick',
+  'changeName',
+  'deleteNode',
+  'downloadNode',
+  'addNode',
+  'addFolder',
+  'onDrop',
+  'setDragEnterNode',
+  'setDragFile',
+  'setDragFolder',
+  'dragStart',
+]);
+// 拿到传入的值
+const props = withDefaults(
+  defineProps<{
+    model: IFileSystem;
+    draggable?: boolean;
+    selected?: IFileSystem;
+  }>(),
+  {
+    draggable: true,
   }
-  // 吐出去的事件
-  const emit = defineEmits([
-    'onClick',
-    'changeName',
-    'deleteNode',
-    'addNode',
-    'addFolder',
-    'onDrop',
-    'setDragEnterNode',
-    'setDragFile',
-    'setDragFolder',
-    'dragStart',
-  ]);
-  // 拿到传入的值
-  const props = withDefaults(
-    defineProps<{
-      model: IFileSystem;
-      draggable?: boolean;
-      selected?: IFileSystem;
-    }>(),
-    {
-      draggable: true,
-    }
-  );
-  //是否移入
-  const isHover = ref(false);
-  // 修改目录名字
-  const editable = ref(false);
-  // 拖拽移入
-  const isDragEnterNode = ref(false);
-  // 是否拖拽文件
-  const isDragFile = ref(false);
-  // 是否展开
-  const expanded = ref(true);
-  // inputRef
-  const nodeInput = ref(null);
-  // 是否是文件夹
-  const isFolder = computed(() => {
-    return props.model.isFolder;
+);
+//是否移入
+const isHover = ref(false);
+// 修改目录名字
+const editable = ref(false);
+// 拖拽移入
+const isDragEnterNode = ref(false);
+// 是否拖拽文件
+const isDragFile = ref(false);
+// 是否展开
+const expanded = ref(true);
+// inputRef
+const nodeInput = ref(null);
+// 是否是文件夹
+const isFolder = computed(() => {
+  return props.model.isFolder;
+});
+const isSelected = computed(() => props.selected.id === props.model.id);
+// 拖拽样式
+const treeNodeClass = computed(() => {
+  return {
+    'vtl-node-main': true,
+    'vtl-active': isDragEnterNode.value,
+    'vtl-active-file': isDragFile.value,
+    selected: isSelected.value,
+  };
+});
+// 最后一个移入的内容保存为了防止重复移入
+let lastenter = null;
+// 删除目录
+const delNode = () => {
+  emit('deleteNode', {
+    ...props.model,
+    eventType: 'delete',
   });
-  const isSelected = computed(() => props.selected.id === props.model.id);
-  // 拖拽样式
-  const treeNodeClass = computed(() => {
-    return {
-      'vtl-node-main': true,
-      'vtl-active': isDragEnterNode.value,
-      'vtl-active-file': isDragFile.value,
-      selected: isSelected.value,
-    };
+};
+//下载目录
+const downNode = () => {
+  emit('downloadNode', {
+    ...props.model,
+    eventType: 'download',
   });
-  // 最后一个移入的内容保存为了防止重复移入
-  let lastenter = null;
-  // 删除目录
-  const delNode = () => {
-    emit('deleteNode', {
+};
+// 选中effect
+watchEffect(() => {
+  const $input = nodeInput.value;
+  if ($input) {
+    // 获取焦点
+    $input.focus();
+    // 设置光标位置
+    $input.setSelectionRange(0, $input.value.length);
+  }
+});
+// 编辑目录名字
+const setEditable = () => {
+  editable.value = true;
+  props.model.isAdd = false; //lxh
+};
+// 修改目录名字
+const setUnEditable = (e) => {
+  if (props.model.isAdd) {
+    console.log('新增文档失去焦点');
+    props.model.isAdd = false;
+    emit('addNode', {
+      id: props.model.id,
+      isFolder: false,
+      newName: props.model.title,
+    });
+  } else if (editable.value) {
+    console.log('编辑文档失去焦点');
+    editable.value = false;
+    props.model.title = e.target.value;
+    emit('changeName', {
+      id: props.model.id,
+      pid: props.model.pid,
+      isAdd: props.model.isAdd,
+      newName: e.target.value,
+      eventType: 'blur',
+      isFolder: isFolder.value,
+    });
+  }
+};
+// 展开收起
+const toggle = () => {
+  if (isFolder.value) {
+    expanded.value = !expanded.value;
+    emit('onClick', {
+      ...props.model,
+    }); //lxh
+  } else {
+    emit('onClick', {
       ...props.model,
-      eventType: 'delete',
     });
-  };
-  // 选中effect
-  watchEffect(() => {
-    const $input = nodeInput.value;
-    if ($input) {
-      // 获取焦点
-      $input.focus();
-      // 设置光标位置
-      $input.setSelectionRange(0, $input.value.length);
-    }
+  }
+};
+// 拖拽结束
+const mouseOver = () => {
+  isHover.value = true;
+};
+// 移出
+const mouseOut = () => {
+  isHover.value = false;
+};
+// // 添加目录
+// const addChildFolder = () => {
+//   props.model.isAdd = true; //lxh
+//   props.model.title = '';//lxh
+//   emit('addFolder', {
+//     id: props.model.id,
+//     isFolder: true,
+//   });
+// };
+// 添加文件
+const addChildDocument = (node) => {
+  props.model.title = ''; //lxh
+  props.model.isAdd = true; //lxh
+  editable.value = false; //
+};
+// 拖拽开始
+const dragStart = () => {
+  console.log(0);
+  emit('dragStart', {
+    ...props.model,
   });
-  // 编辑目录名字
-  const setEditable = () => {
-    editable.value = true;
-    props.model.isAdd = false; //lxh
-  };
-  // 修改目录名字
-  const setUnEditable = (e) => {
-    if (props.model.isAdd) {
-      console.log('新增文档失去焦点');
-      props.model.isAdd = false;
-      emit('addNode', {
-        id: props.model.id,
-        isFolder: false,
-        newName: props.model.title,
-      });
-    } else if (editable.value) {
-      console.log('编辑文档失去焦点');
-      editable.value = false;
-      props.model.title = e.target.value;
-      emit('changeName', {
-        id: props.model.id,
-        pid: props.model.pid,
-        isAdd: props.model.isAdd,
-        newName: e.target.value,
-        eventType: 'blur',
-        isFolder: isFolder.value,
-      });
-    }
-  };
-  // 展开收起
-  const toggle = () => {
+};
+const dragOver = (e) => {
+  e.preventDefault();
+  return true;
+};
+
+const dragEnter = (e) => {
+  lastenter = e.target;
+  console.log('进入', props.model.id);
+  // 由于 dragEnter 发生在 dragLeave 之前,导致必须要使用定时器做一个延时
+  setTimeout(() => {
     if (isFolder.value) {
-      expanded.value = !expanded.value;
-      emit('onClick', {
-        ...props.model,
-      }); //lxh
+      expanded.value = true;
+      isDragFile.value = true;
     } else {
-      emit('onClick', {
-        ...props.model,
-      });
+      emit('setDragFile', true);
     }
-  };
-  // 拖拽结束
-  const mouseOver = () => {
-    isHover.value = true;
-  };
-  // 移出
-  const mouseOut = () => {
-    isHover.value = false;
-  };
-  // // 添加目录
-  // const addChildFolder = () => {
-  //   props.model.isAdd = true; //lxh
-  //   props.model.title = '';//lxh
-  //   emit('addFolder', {
-  //     id: props.model.id,
-  //     isFolder: true,
-  //   });
-  // };
-  // 添加文件
-  const addChildDocument = (node) => {
-    props.model.title = ''; //lxh
-    props.model.isAdd = true; //lxh
-    editable.value = false; //
-  };
-  // 拖拽开始
-  const dragStart = () => {
-    console.log(0);
-    emit('dragStart', {
-      ...props.model,
-    });
-  };
-  const dragOver = (e) => {
-    e.preventDefault();
-    return true;
-  };
-
-  const dragEnter = (e) => {
-    lastenter = e.target;
-    console.log('进入', props.model.id);
-    // 由于 dragEnter 发生在 dragLeave 之前,导致必须要使用定时器做一个延时
-    setTimeout(() => {
-      if (isFolder.value) {
-        expanded.value = true;
-        isDragFile.value = true;
-      } else {
-        emit('setDragFile', true);
-      }
-      isDragEnterNode.value = true;
-      emit('setDragEnterNode', true);
-    });
-  };
-  const dragLeave = (e) => {
-    // 为了防止多次选中问题
-    if (lastenter == e.target) {
-      console.log('离开', props.model.id);
-      if (isFolder.value) {
-        isDragFile.value = false;
-      } else {
-        emit('setDragFile', false);
-      }
-      emit('setDragEnterNode', false);
-      isDragEnterNode.value = false;
-    }
-  };
-  const drop = (e) => {
-    isDragFile.value = false;
-    isDragEnterNode.value = false;
-    emit('setDragEnterNode', false);
-    emit('setDragFile', false);
-    // 为了获取路径需要判断是不是文件夹,如果不是文件夹向上找
+    isDragEnterNode.value = true;
+    emit('setDragEnterNode', true);
+  });
+};
+const dragLeave = (e) => {
+  // 为了防止多次选中问题
+  if (lastenter == e.target) {
+    console.log('离开', props.model.id);
     if (isFolder.value) {
-      emit('onDrop', props.model);
+      isDragFile.value = false;
     } else {
-      if (props.model.pid) {
-        emit('setDragFolder');
-      } else {
-        emit('onDrop', props.model);
-      }
+      emit('setDragFile', false);
     }
-  };
-  const setDragEnterNode = (bol) => {
-    isDragEnterNode.value = bol;
-  };
-  const setDragFile = (bol) => {
-    isDragFile.value = bol;
-  };
-  // 找到文件夹
-  const setDragFolder = () => {
+    emit('setDragEnterNode', false);
+    isDragEnterNode.value = false;
+  }
+};
+const drop = (e) => {
+  isDragFile.value = false;
+  isDragEnterNode.value = false;
+  emit('setDragEnterNode', false);
+  emit('setDragFile', false);
+  // 为了获取路径需要判断是不是文件夹,如果不是文件夹向上找
+  if (isFolder.value) {
     emit('onDrop', props.model);
-  };
+  } else {
+    if (props.model.pid) {
+      emit('setDragFolder');
+    } else {
+      emit('onDrop', props.model);
+    }
+  }
+};
+const setDragEnterNode = (bol) => {
+  isDragEnterNode.value = bol;
+};
+const setDragFile = (bol) => {
+  isDragFile.value = bol;
+};
+// 找到文件夹
+const setDragFolder = () => {
+  emit('onDrop', props.model);
+};
 </script>
 <style lang="less">
-  .vtl-node {
-    .vtl-node-main {
-      display: flex;
-      align-items: center;
-      padding: 2px 0 2px 2px;
-      cursor: pointer;
+.vtl-node {
+  .vtl-node-main {
+    display: flex;
+    align-items: center;
+    padding: 2px 0 2px 2px;
+    cursor: pointer;
 
-      &:hover {
-        .vtl-border-text {
-          width: 80%;
-        }
+    &:hover {
+      .vtl-border-text {
+        width: 80%;
       }
+    }
 
-      .vtl-border-text {
-        display: flex; //lxh
-        flex: 1;
-        align-items: center; //lxh
-        width: 100%;
-        padding-left: 5px;
+    .vtl-border-text {
+      display: flex; //lxh
+      flex: 1;
+      align-items: center; //lxh
+      width: 100%;
+      padding-left: 5px;
 
-        .iconfont {
-          width: 16px;
-          height: 16px;
-          vertical-align: text-bottom;
-        }
+      .iconfont {
+        width: 16px;
+        height: 16px;
+        vertical-align: text-bottom;
       }
+    }
 
-      &.selected {
-        // background-color: rgba(45, 113, 134, 0.2);
-        background-color: #1c4869;
-      }
+    &.selected {
+      // background-color: rgba(45, 113, 134, 0.2);
+      background-color: #1c4869;
+    }
 
-      .vtl-input {
-        border: none;
-        max-width: 150px;
-        padding: 5px 0;
-        padding-left: 5px;
-        margin-left: 5px;
+    .vtl-input {
+      border: none;
+      max-width: 150px;
+      padding: 5px 0;
+      padding-left: 5px;
+      margin-left: 5px;
 
-        &:focus {
-          outline: none;
-        }
+      &:focus {
+        outline: none;
       }
+    }
+
+    .vtl-node-content {
+      color: #fff;
+      padding-left: 5px;
+      font-size: 14px;
+      width: 80%;
+      display: inline-block;
+      vertical-align: bottom;
+    }
 
+    &:hover {
       .vtl-node-content {
         color: #fff;
-        padding-left: 5px;
-        font-size: 14px;
-        width: 80%;
-        display: inline-block;
-        vertical-align: bottom;
-      }
-
-      &:hover {
-        .vtl-node-content {
-          color: #fff;
-          overflow: hidden;
-        }
+        overflow: hidden;
       }
+    }
 
-      &.vtl-active {
-        * {
-          pointer-events: none;
-        }
+    &.vtl-active {
+      * {
+        pointer-events: none;
       }
+    }
 
-      &.vtl-active-file {
-        outline: 2px dashed #353f51;
-      }
+    &.vtl-active-file {
+      outline: 2px dashed #353f51;
+    }
 
-      .vtl-operation {
-        padding-right: 10px;
-      }
+    .vtl-operation {
+      padding-right: 10px;
     }
   }
+}
 
-  .vtl-tree-margin {
-    padding-left: 1em;
-  }
+.vtl-tree-margin {
+  padding-left: 1em;
+}
 </style>

+ 7 - 1
src/views/vent/performance/fileDetail/fileDetail.api.ts

@@ -13,10 +13,16 @@ enum Api {
   commit = '/safety/actBusiness/commit',
   getNowUserAgencyData = '/safety/approvalBusiness/getNowUserAgencyData',
   getNowUserApprovedData = '/safety/approvalBusiness/getNowUserApprovedData',
-  sumVentReport='/ventanaly-company/company/reportData/sumVentReport'
+  sumVentReport='/ventanaly-company/company/reportData/sumVentReport',
+  zipdownload='/ventanaly-sharefile/fileServer/zipdownload'
 }
 
 /**
+ * 下载文件目录
+ * @param params
+ */
+export const zipdownload = (params) => defHttp.post({ url: Api.zipdownload, params, responseType: 'blob' },{ joinParamsToUrl: true });
+/**
  * 汇总集团通风报表
  * @param params
  */

+ 5 - 4
src/views/vent/performance/fileDetail/fileDetail.data.ts

@@ -17,6 +17,7 @@ export const columns: BasicColumn[] = [
     title: '文件名称',
     dataIndex: 'fileName',
     align:'center',
+    width:160,
   },
 
   {
@@ -28,7 +29,7 @@ export const columns: BasicColumn[] = [
   {
     title: '文件来源',
     dataIndex: 'fileSource',
-    width:160,
+    width:140,
     align:'center',
   },
   // {
@@ -39,7 +40,7 @@ export const columns: BasicColumn[] = [
   {
     title: '上传时间',
     dataIndex: 'createTime',
-    width:180,
+    width:160,
     align:'center',
   },
   {
@@ -57,14 +58,14 @@ export const columns: BasicColumn[] = [
   {
     title: '审批操作',
     dataIndex: 'actionSp',
-    width: 200,
+    width: 180,
     align: 'center',
     slots: { customRender: 'actionSp' },
   },
   {
     title: '文件操作',
     dataIndex: 'actionWj',
-    width: 200,
+    width: 180,
     align: 'center',
     slots: { customRender: 'actionWj' },
   },

+ 36 - 7
src/views/vent/performance/fileDetail/index.vue

@@ -5,7 +5,7 @@
       <div class="left-box">
         <!-- 左侧树菜单 -->
         <fileSystem :selected="selected" :list="listArr" :draggable="true" @delete-node="onDeltet" @on-click="onClick"
-          @change-name="onChangeName" @addNode="onAddNode">
+          @change-name="onChangeName" @addNode="onAddNode" @downloadNode="downloadNode">
           <template #icon="{ item }">
             <template v-if="item.isFolder">
               <SvgIcon v-if="item.expanded" size="18" name="file-open" />
@@ -14,12 +14,14 @@
             <treeIcon class="iconfont" :title="item.title" v-else />
           </template>
           <template #operation="{ type }">
+
             <i class="iconfont icon-xinzeng" v-if="type == 'addDocument'"></i>
             <i class="iconfont icon-bianji" v-if="type == 'Editable'"></i>
             <a-popconfirm v-if="type == 'deleteNode'" title="是否确认删除!" ok-text="确定" cancel-text="取消"
               @confirm="confirmDel">
               <i class="iconfont icon-guanbi"></i>
             </a-popconfirm>
+            <i class="iconfont icon-shangchuan1" v-if="type == 'downloadNode'"></i>
           </template>
         </fileSystem>
       </div>
@@ -89,7 +91,7 @@ import { useMessage } from '/@/hooks/web/useMessage';
 import { SvgIcon } from '/@/components/Icon';
 import { ref, onMounted, reactive, nextTick, watch } from 'vue';
 import { columns } from './fileDetail.data';
-import { getTree, createFile, editMenu, delMenu, uploadApi, downLoad, deleteById, listData, getNowUserAgencyData, sumVentReport } from './fileDetail.api';
+import { getTree, createFile, editMenu, delMenu, uploadApi, downLoad, deleteById, listData, getNowUserAgencyData, sumVentReport, zipdownload } from './fileDetail.api';
 
 let activeKey = ref('1');
 let selfParam = reactive({
@@ -144,7 +146,34 @@ let listArr = reactive<any[]>([]);
 //获取要删除的节点数据
 let delNode = reactive({});
 
-
+//下载目录
+function downloadNode(data) {
+  console.log(data, '999000=============================================')
+  zipdownload({ id: data.id, ifMine: false }).then((res) => {
+    let filename = `${data.fileName}`;
+    downFilePublic(res, filename);
+  });
+}
+// 下载公用方法
+function downFilePublic(content, fileName) {
+  const blob = new Blob([content]); // 构造一个blob对象来处理数据
+  // 对于<a>标签,只有 Firefox 和 Chrome(内核) 支持 download 属性
+  // IE10以上支持blob但是依然不支持download
+  if ('download' in document.createElement('a')) {
+    // 支持a标签download的浏览器
+    const link = document.createElement('a'); // 创建a标签
+    link.download = fileName; // a标签添加属性
+    link.style.display = 'none';
+    link.href = URL.createObjectURL(blob);
+    document.body.appendChild(link);
+    link.click(); // 执行下载
+    URL.revokeObjectURL(link.href); // 释放url
+    document.body.removeChild(link); // 释放标签
+  } else {
+    // 其他浏览器
+    navigator.msSaveBlob(blob, fileName);
+  }
+}
 //汇总报表
 async function reportSum() {
   let res = await sumVentReport()
@@ -389,9 +418,9 @@ onMounted(() => {
     z-index: 999;
 
     .left-box {
-      width: 15%;
+      width: 18%;
       height: 100%;
-      padding: 20px;
+      padding: 10px;
       border: 1px solid #99e8ff66;
       background: #27546e1a;
       box-shadow: 0px 0px 20px 7px rgba(145, 233, 254, 0.7) inset;
@@ -407,9 +436,9 @@ onMounted(() => {
     }
 
     .right-box {
-      width: 85%;
+      width: 82%;
       height: 100%;
-      padding: 0px 0px 0px 15px;
+      padding: 0px 0px 0px 10px;
       box-sizing: border-box;
 
       .search {

+ 0 - 139
src/views/vent/reportManager/comment/report-add.vue

@@ -1,139 +0,0 @@
-<template>
-    <div class="report-add">
-        <a-form :model="formState" labelAlign="center" :label-col="{ span: 8 }" :wrapper-col="{ span: 16 }">
-            <a-form-item label="所属部门编号:" >
-          <a-select v-model:value="formState.sysOrgCode" placeholder="请选择...">
-            <a-select-option v-for="item in sysOrgCodeList" :key="item.value">{{ item.label }}</a-select-option>
-          </a-select>
-        </a-form-item>
-            <a-form-item label="数据名称:">
-                <a-input v-model:value="formState.name" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="集团报表单元格所在sheet页:">
-                <a-input v-model:value="formState.groupSheet" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="集团报表单元格所在列:">
-                <a-input v-model:value="formState.groupCol" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="集团报表单元格所在行:">
-                <a-input v-model:value="formState.groupRow" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="矿报表单元格:">
-                <a-input v-model:value="formState.sheet" placeholder="请输入sheet页,多个值中间用逗号隔开" style="width:330px;" />
-                <a-input v-model:value="formState.col" placeholder="请输入col列,多个值中间用逗号隔开" style="width:330px;margin:0px 10px" />
-                <a-input v-model:value="formState.row" placeholder="请输入row行,多个值中间用逗号隔开" style="width:330px" />
-            </a-form-item>
-            <a-form-item label="是否计算:">
-                <a-radio-group v-model:value="formState.isCompute" name="radioGroup">
-                    <a-radio :value=true>是</a-radio>
-                    <a-radio :value=false>否</a-radio>
-                </a-radio-group>
-            </a-form-item>
-            <a-form-item label="计算公式:">
-                <JDictSelectTag v-model:value="formState.formula" placeholder="请选择计算公式..." dictCode="report_formula" />
-            </a-form-item>
-        </a-form>
-        <div class="confirm-btn">
-            <a-button type="primary" @click="getReportAdd">添加</a-button>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { ref, reactive,onMounted } from 'vue'
-import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
-import { reportAdd,queryDepartTreeSync } from '../reportManager.api'
-
-let formState = reactive({
-    sysOrgCode:'',
-    formula: '',
-    groupCol: '',
-    groupRow: '',
-    groupSheet: '',
-    isCompute: true,
-    mineCells: [],
-    sheet:'',
-    col:'',
-    row:'',
-    name: ''
-})
-//所属部门编号列表
-let sysOrgCodeList=reactive<any[]>([])
-
-async function getReportAdd(){
-    formState.mineCells.length=0
-    let paramRow=formState.row.split(',')
-    let paramCol=formState.col.split(',')
-    let paramSheet=formState.sheet.split(',')
-    paramRow.forEach((el,index)=>{
-        formState.mineCells.push({sheet:paramSheet[index],col:paramCol[index],row:paramRow[index]})
-    })
-    console.log(formState,'formState------------')
-    let res=await reportAdd({sysOrgCode:formState.sysOrgCode,formula:formState.formula,groupCol:formState.groupCol,groupRow:formState.groupRow, groupSheet:formState.groupSheet,isCompute:formState.isCompute,mineCells:JSON.stringify(formState.mineCells),name:formState.name})
-    console.log(res,'res9999------------------')
-}
-
-//获取所属部门编号列表数据
-async function queryDepartTreeSyncList(){
-    let res=await queryDepartTreeSync()
-    console.log(res,'部门编号列表--------')
-    sysOrgCodeList.length=0
-    if(res.length!=0){
-        res.forEach(el=>{
-            sysOrgCodeList.push({label:el.title,value:el.orgCode})
-        })
-    }
-}
-
-onMounted(()=>{
-    queryDepartTreeSyncList()
-})
-
-</script>
-
-<style lang="less" scoped>
-.report-add {
-    position: relative;
-    width: 100%;
-    height: 100%;
-    padding: 30px 10px;
-    margin: 0 auto;
-    box-sizing: border-box
-}
-
-.zxm-form {
-    width: 80%;
-    margin-bottom: 20px;
-}
-
-.confirm-btn {
-    position: absolute;
-    bottom: 290px;
-    left: 50%;
-    transform: translate(-50%,0);
-    height: 40px;
-  
-}
-
-:deep(.zxm-form-item-label > label) {
-    color: #fff;
-}
-:deep(.zxm-select-selector) {
-    width: 100%;
-    color: #fff ;
-    border: 1px solid #3ad8ff77 !important;
-    background-color: #ffffff00 !important;
-}
-:deep(.zxm-select-selection-item){
-    color: #fff !important;
-}
-:deep(.zxm-select-selection-placeholder){
-    color: #ccc !important;
-}
-:deep(.zxm-input){
-    color: #fff;
-    border: 1px solid #3ad8ff77 !important;
-    background-color: #ffffff00 !important;
-}
-
-</style>

+ 178 - 0
src/views/vent/reportManager/comment/report-modal.vue

@@ -0,0 +1,178 @@
+<template>
+    <div class="report-add">
+        <a-form :model="formStates" labelAlign="center" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
+            <a-form-item label="所属部门编号:">
+                <a-select v-model:value="formStates.sysOrgCode" placeholder="请选择...">
+                    <a-select-option v-for="item in sysOrgCodeList" :key="item.value">{{ item.label }}</a-select-option>
+                </a-select>
+            </a-form-item>
+            <a-form-item label="数据名称:">
+                <a-input v-model:value="formStates.name" placeholder="请输入..." />
+            </a-form-item>
+            <a-form-item label="集团报表单元格所在sheet页:">
+                <a-input v-model:value="formStates.groupSheet" placeholder="请输入..." />
+            </a-form-item>
+            <a-form-item label="集团报表单元格所在列:">
+                <a-input v-model:value="formStates.groupCol" placeholder="请输入..." />
+            </a-form-item>
+            <a-form-item label="集团报表单元格所在行:">
+                <a-input v-model:value="formStates.groupRow" placeholder="请输入..." />
+            </a-form-item>
+            <a-form-item label="矿报表单元格:">
+                <a-input v-model:value="formStates.sheet" placeholder="请输入sheet页,多个值中间用逗号隔开" style="width:189px;" />
+                <a-input v-model:value="formStates.col" placeholder="请输入col列,多个值中间用逗号隔开"
+                    style="width:188px;margin:0px 10px" />
+                <a-input v-model:value="formStates.row" placeholder="请输入row行,多个值中间用逗号隔开" style="width:189px" />
+            </a-form-item>
+            <a-form-item label="是否计算:">
+                <a-radio-group v-model:value="formStates.isCompute" name="radioGroup">
+                    <a-radio :value=true>是</a-radio>
+                    <a-radio :value=false>否</a-radio>
+                </a-radio-group>
+            </a-form-item>
+            <a-form-item label="计算公式:">
+                <JDictSelectTag v-model:value="formStates.formula" placeholder="请选择计算公式..." dictCode="report_formula" />
+            </a-form-item>
+        </a-form>
+        <div class="confirm-btn">
+            <a-button type="primary" @click="getConfirm" style="margin-right:15px">确定</a-button>
+            <a-button type="plain" @click="getCancel">取消</a-button>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, onMounted, watch } from 'vue'
+import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
+import { reportAdd, reportEdit } from '../reportManager.api'
+
+let props = defineProps({
+    sysOrgCodeList: {
+        type: Array,
+        default: () => {
+            return []
+        }
+    },
+    formState: {
+        type: Object,
+        default: () => {
+            return {}
+        }
+    },
+    isToggle: {
+        type: String,
+        default: ''
+    }
+})
+
+let formStates = reactive({
+    sysOrgCode: '',
+    formula: '',
+    groupCol: '',
+    groupRow: '',
+    groupSheet: '',
+    isCompute: true,
+    mineCells: [],
+    sheet: '',
+    col: '',
+    row: '',
+    name: ''
+})
+let emit = defineEmits(['Close']);
+
+async function getConfirm() {
+    let mineCells = []
+    let paramRow = formStates.row.split(',')
+    let paramCol = formStates.col.split(',')
+    let paramSheet = formStates.sheet.split(',')
+    paramRow.forEach((el, index) => {
+        mineCells.push({ sheet: paramSheet[index], col: paramCol[index], row: paramRow[index] })
+    })
+    console.log(mineCells, 'formStates------------')
+    if (props.isToggle == 'add') {
+
+        let res = await reportAdd({ sysOrgCode: formStates.sysOrgCode, formula: formStates.formula, groupCol: formStates.groupCol, groupRow: formStates.groupRow, groupSheet: formStates.groupSheet, isCompute: formStates.isCompute, mineCells: JSON.stringify(mineCells), name: formStates.name })
+        console.log(res, '新增------------------')
+        emit('Close');
+
+    } else {
+
+        let res = await reportEdit({ sysOrgCode: formStates.sysOrgCode, formula: formStates.formula, groupCol: formStates.groupCol, groupRow: formStates.groupRow, groupSheet: formStates.groupSheet, isCompute: formStates.isCompute, mineCells: JSON.stringify(mineCells), name: formStates.name })
+        console.log(res, '编辑------------------')
+        emit('Close');
+    }
+
+}
+
+watch(() => props.formState, (newV) => {
+    formStates = Object.assign(formStates, newV)
+    let row = []
+    let col = []
+    let sheet = []
+    if (props.isToggle == 'edit') {
+        JSON.parse(formStates.mineCells).forEach(el => {
+            row.push(el.row)
+            col.push(el.col)
+            sheet.push(el.sheet)
+        })
+        formStates.col = col.join(',')
+        formStates.row = row.join(',')
+        formStates.sheet = sheet.join(',')
+    }
+
+}, {
+    immediate: true,
+    deep: true
+})
+
+
+
+onMounted(() => { })
+
+</script>
+
+<style lang="less" scoped>
+.report-add {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    padding: 10px;
+    box-sizing: border-box
+}
+
+.zxm-form {
+    width: 80%;
+    margin: 0px auto;
+}
+
+.confirm-btn {
+    width: 100%;
+    margin: 10px 0px;
+    text-align: center;
+}
+
+:deep(.zxm-form-item-label > label) {
+    color: #fff;
+}
+
+:deep(.zxm-select-selector) {
+    width: 100%;
+    color: #fff;
+    border: 1px solid #3ad8ff77 !important;
+    background-color: #ffffff00 !important;
+}
+
+:deep(.zxm-select-selection-item) {
+    color: #fff !important;
+}
+
+:deep(.zxm-select-selection-placeholder) {
+    color: #ccc !important;
+}
+
+:deep(.zxm-input) {
+    color: #fff;
+    border: 1px solid #3ad8ff77 !important;
+    background-color: #ffffff00 !important;
+}
+</style>

+ 200 - 0
src/views/vent/reportManager/comment/reportMap.vue

@@ -0,0 +1,200 @@
+<template>
+    <div class="report-map">
+        <div class="search-area">
+            <a-select v-model:value="searchForm.sysOrgCode" style="width:280px;margin-right:15px"
+                placeholder="请选择部门...">
+                <a-select-option v-for="item in sysOrgCodeList" :key="item.value">{{ item.label }}</a-select-option>
+            </a-select>
+            <a-button type="primary" preIcon="ant-design:search-outlined" style="margin-right:15px"
+                @click="getSearch">查询</a-button>
+            <a-button preIcon="ant-design:sync-outlined" @click="onReset">重置</a-button>
+        </div>
+        <a-button preIcon="ant-design:plus-outlined" type="primary" @click="handleAdd" style="margin-bottom: 10px">新增</a-button>
+        <a-table size="small" :dataSource="dataSource" :columns="columnsMap" :scroll="{ y: 620 }"
+            :pagination="pagination" @change="pageChange">
+            <template #action="{ record }">
+                <a class="table-action-link" @click="handleEdit(record)">编辑</a>
+                <a class="table-action-link" @click="handleDel(record)">删除</a>
+            </template>
+        </a-table>
+        <!-- 添加/编辑弹窗 -->
+        <a-modal v-model:visible="visibleMap" width="1000px" :footer="null" :title="titleMap" centered destroyOnClose>
+            <reportModal :isToggle="isToggle" :sysOrgCodeList="sysOrgCodeList" :formState="formState" @Close="Close">
+            </reportModal>
+        </a-modal>
+    </div>
+</template>
+
+<script setup lang="ts">
+//ts语法
+import { ref, reactive, toRaw, watch, onMounted } from 'vue';
+import { listMap, queryDepartTreeSync, reportDel } from '../reportManager.api'
+import { columnsMap, searchForm } from '../reportManager.data'
+import reportModal from './report-modal.vue'
+
+let dataSource = ref<any[]>([])
+let searchForm = reactive({
+    sysOrgCode: '',
+})
+let sysOrgCodeList = reactive<any[]>([])
+//分页参数配置
+let pagination = reactive({
+    current: 1, // 当前页码
+    pageSize: 10, // 每页显示条数
+    total: 0, // 总条目数,后端返回
+    // showTotal: (total, range) => `${range[0]}-${range[1]} 条,总共 ${total} 条`, // 分页右下角显示信息
+    showSizeChanger: true, // 是否可改变每页显示条数
+    pageSizeOptions: ['10', '20', '50',], // 可选的每页显示条数
+})
+let visibleMap = ref(false)
+let titleMap = ref('')
+let isToggle = ref('')
+let formState = reactive({
+    sysOrgCode: '',
+    formula: '',
+    groupCol: '',
+    groupRow: '',
+    groupSheet: '',
+    isCompute: true,
+    mineCells: [],
+    sheet: '',
+    col: '',
+    row: '',
+    name: ''
+})
+
+
+//关闭弹窗
+function Close() {
+    visibleMap.value = false
+    pagination.current = 1
+    getListMap()
+}
+//添加
+function handleAdd() {
+    titleMap.value = '新增报表映射'
+    visibleMap.value = true
+    isToggle.value = 'add'
+    formState = {
+        sysOrgCode: '',
+        formula: '',
+        groupCol: '',
+        groupRow: '',
+        groupSheet: '',
+        isCompute: true,
+        mineCells: [],
+        sheet: '',
+        col: '',
+        row: '',
+        name: ''
+    }
+
+}
+//编辑
+function handleEdit(record) {
+    titleMap.value = '编辑报表映射'
+    visibleMap.value = true
+    isToggle.value = 'edit'
+
+    formState = {
+        sysOrgCode: record.sysOrgCode,
+        formula: record.formula,
+        groupCol: record.groupCol,
+        groupRow: record.groupRow,
+        groupSheet: record.groupSheet,
+        isCompute: record.isCompute,
+        mineCells: record.mineCells,
+        sheet: record.sheet,
+        col: record.col,
+        row: record.row,
+        name: record.name
+    }
+    console.log(formState, '00000===========')
+
+}
+//删除
+async function handleDel(record) {
+    await reportDel({ id: record.id })
+    pagination.current = 1
+    getListMap()
+}
+
+//分页切换
+function pageChange(val) {
+    pagination.current = val.current
+    pagination.pageSize = val.pageSize
+    getListMap()
+}
+//获取所属部门编号列表数据
+async function queryDepartTreeSyncList() {
+    let res = await queryDepartTreeSync()
+    console.log(res, '部门编号列表--------')
+    sysOrgCodeList.length = 0
+    if (res.length != 0) {
+        res.forEach(el => {
+            sysOrgCodeList.push({ label: el.title, value: el.orgCode })
+        })
+    }
+}
+
+//获取数据列表
+async function getListMap() {
+    let res = await listMap({ sysOrgCode: searchForm.sysOrgCode, pageNo: pagination.current, pageSize: pagination.pageSize, })
+    console.log(res, 'res=========')
+    if (res.records && res.records.length != 0) {
+        dataSource.value = res.records
+        pagination.total = res.total
+    } else {
+        dataSource.value = res.records
+    }
+}
+//查询
+function getSearch() {
+    pagination.current = 1
+    getListMap()
+}
+//重置
+function onReset() {
+    pagination.current = 1
+    searchForm.sysOrgCode = ''
+    getListMap()
+}
+
+
+onMounted(() => {
+    queryDepartTreeSyncList()
+    getListMap()
+})
+
+</script>
+
+<style lang="less" scoped>
+.report-map {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    padding: 10px;
+    box-sizing: border-box;
+
+    .search-area {
+        display: flex;
+        height: 60px;
+        align-items: center;
+
+    }
+}
+
+:deep(.zxm-select-selector) {
+    width: 100%;
+    color: #fff;
+    border: 1px solid #3ad8ff77 !important;
+    background-color: #ffffff00 !important;
+}
+
+:deep(.zxm-select-selection-item) {
+    color: #fff !important;
+}
+
+// :deep(.zxm-select-selection-placeholder) {
+//     color: #ccc !important;
+// }</style>

+ 23 - 1
src/views/vent/reportManager/reportManager.api.ts

@@ -12,11 +12,20 @@ enum Api {
   getUpload = '/safety/reportInfo/upload',
   reportAdd= '/ventanaly-company/company/reportData/add',
   queryDepartTreeSync= '/sys/sysDepart/queryDepartTreeSync',
-  synReportFile='/safety/reportInfo/synReportFile'
+  synReportFile='/safety/reportInfo/synReportFile',
+  listMap='/ventanaly-company/company/reportData/list',
+  reportEdit='/ventanaly-company/company/reportData/edit',
+  reportDel='/ventanaly-company/company/reportData/delete'
+
 
 }
 
 /**
+ * 报表数据映射列表
+ * @param params
+ */
+export const listMap = (params) => defHttp.get({ url: Api.listMap, params });
+/**
  * 同步报表到文件共享中心
  * @param params
  */
@@ -33,6 +42,19 @@ export const queryDepartTreeSync = () => defHttp.get({ url: Api.queryDepartTreeS
  * @param params
  */
 export const reportAdd = (params) => defHttp.post({ url: Api.reportAdd, params });
+/**
+ * 报表数据映射-编辑
+ * @param params
+ */
+export const reportEdit = (params) => defHttp.post({ url: Api.reportEdit, params });
+/**
+ * 报表数据映射-删除
+ */
+export const reportDel = (params, handleSuccess) => {
+  return defHttp.delete({ url: Api.reportDel, params }, { joinParamsToUrl: true }).then(() => {
+    handleSuccess();
+  });
+};
 
 /**
  * 列表接口

+ 66 - 0
src/views/vent/reportManager/reportManager.data.ts

@@ -107,4 +107,70 @@ export const columns: BasicColumn[] = [
       dataIndex: 'reportVersion',
       width: 100,
     },
+  ];
+
+  //数据映射报表
+  export const columnsMap: BasicColumn[] = [
+    {
+      title: '序号',
+      width: 60,
+      align: 'center',
+      customRender: ({ index }: { index: number }) => `${index + 1}`
+    },
+    {
+      title: '所属矿名称',
+      dataIndex: 'sysOrgName',
+      align:'center',
+      width:120
+    },
+  
+    {
+      title: '数据名称',
+      dataIndex: 'name',
+      align:'center',
+     
+    },
+    {
+      title: '矿报表单元格',
+      dataIndex: 'mineCells',
+      align:'center',
+   
+    },
+    {
+      title: '集团报表单元格所在列',
+      dataIndex: 'groupCol',
+      align:'center',
+      width:120
+    },
+    {
+      title: '集团报表单元格所在行',
+      dataIndex: 'groupRow',
+      align:'center',
+      width:120
+    },
+    {
+      title: '集团报表单元格所在sheet页',
+      dataIndex: 'groupSheet',
+      align:'center',
+      width:120
+    },
+    {
+      title: '是否计算',
+      dataIndex: 'isCompute',
+      align:'center',
+      width:120
+    },
+    {
+      title: '	计算公式',
+      dataIndex: 'formula',
+      align:'center',
+      width:120
+    },
+    {
+      title: '操作',
+      dataIndex: 'action',
+      width: 200,
+      align: 'center',
+      slots: { customRender: 'action' },
+    },
   ];