Quellcode durchsuchen

数据统计完善

sunxuewei vor 1 Jahr
Ursprung
Commit
ffb87c3c9d

+ 2 - 2
.env.development

@@ -2,9 +2,9 @@
2 2
 # VUE_APP_BASE_URL = 'http://192.168.50.205:9999'
3 3
 # VUE_APP_BASE_URL = 'http://172.16.6.217:9999'
4 4
 # 测试环境外网
5
- VUE_APP_BASE_URL = 'http://121.36.17.6:9098'
5
+#  VUE_APP_BASE_URL = 'http://121.36.17.6:9098'
6 6
 # 正式环境外网
7
-# VUE_APP_BASE_URL = 'http://121.36.17.6:9099'
7
+VUE_APP_BASE_URL = 'http://121.36.17.6:9099'
8 8
 
9 9
 # 图片地址
10 10
 VUE_APP_BASE_IMG_URL = ""

+ 7 - 6
src/api/index.ts

@@ -131,7 +131,7 @@ request.interceptors.response.use(
131 131
   (error) => {
132 132
     NProgress.done();
133 133
     const status = error.response.status;
134
-    const msg = error.response.data.msg;
134
+    const msg = error.response.data.msg || "数据异常,请稍后再试";
135 135
     if (status === 424) {
136 136
       ElMessageBox.confirm("令牌状态已过期,请点击重新登录", "系统提示", {
137 137
         confirmButtonText: "重新登录",
@@ -144,6 +144,12 @@ request.interceptors.response.use(
144 144
         });
145 145
       });
146 146
       return Promise.reject(error);
147
+    } else {
148
+      ElMessage({
149
+        message: msg,
150
+        type: "error",
151
+        duration: 5 * 1000
152
+      });
147 153
     }
148 154
 
149 155
     // let { message } = error;
@@ -152,11 +158,6 @@ request.interceptors.response.use(
152 158
     // } else if (message.includes("timeout")) {
153 159
     //   message = "系统接口请求超时";
154 160
     // } else if (message.includes("Request failed with status code")) {
155
-    ElMessage({
156
-      message: msg,
157
-      type: "error",
158
-      duration: 5 * 1000
159
-    });
160 161
     // }
161 162
     return Promise.reject(error);
162 163
   }

+ 93 - 30
src/components/export2xlsx/index.ts

@@ -1,51 +1,114 @@
1
-import type { Range } from "xlsx";
2
-import { writeFile, utils } from "xlsx";
1
+import { Workbook } from "exceljs";
3 2
 
4 3
 export const exportExcel = (fileData: any[], headerName: any[], headerProp: string[], fileName: string) => {
5
-  // console.log(fileData, headerName, headerProp, fileName);
6 4
   const repeatingData: any = {};
7 5
   const name: string[][] = [[], [], []];
8 6
   const data = fileData.map((obj) => {
9 7
     return headerProp.map((prop) => obj[prop]);
10 8
   });
11
-  name[0].push("省份", "储备仓库", ...headerName.map((item) => item.matypename2));
12
-  name[1].push("省份", "储备仓库", ...headerName.map((item) => item.matypename3));
13
-  name[2].push("省份", "储备仓库", ...headerName.map((item) => item.matypename4));
9
+
10
+  function computedCol(val: number) {
11
+    const header = [
12
+      "A",
13
+      "B",
14
+      "C",
15
+      "D",
16
+      "E",
17
+      "F",
18
+      "G",
19
+      "H",
20
+      "I",
21
+      "J",
22
+      "K",
23
+      "L",
24
+      "M",
25
+      "N",
26
+      "O",
27
+      "P",
28
+      "Q",
29
+      "R",
30
+      "S",
31
+      "T",
32
+      "U",
33
+      "V",
34
+      "W",
35
+      "X",
36
+      "Y",
37
+      "Z"
38
+    ];
39
+    const first = Math.floor(val / 26);
40
+    if (first > 0) {
41
+      return `${header[first - 1]}${header[val % 26]}`;
42
+    } else {
43
+      return `${header[val % 26]}`;
44
+    }
45
+  }
46
+  name[0].push("省份", "储备仓库", ...headerName.map((item) => item.matypename2), "数量总计(件)", "总价值(万元)");
47
+  name[1].push("省份", "储备仓库", ...headerName.map((item) => item.matypename3), "数量总计(件)", "总价值(万元)");
48
+  name[2].push("省份", "储备仓库", ...headerName.map((item) => item.matypename4), "数量总计(件)", "总价值(万元)");
14 49
   name[0].forEach((item, index) => {
15 50
     const itemIndex = name[0].findIndex((ite) => ite === item);
16 51
     if (itemIndex !== index) {
17
-      repeatingData[item] = { s: { r: 0, c: itemIndex }, e: { r: 0, c: index } };
52
+      repeatingData[item] = `${computedCol(index)}1:${computedCol(itemIndex)}1`;
18 53
     }
19 54
   });
20 55
   const cols = data.map((item) => item[0]);
21 56
   cols.forEach((item, index) => {
22 57
     const itemIndex = cols.findIndex((ite) => ite === item);
23 58
     if (itemIndex !== index) {
24
-      repeatingData[item] = { s: { r: itemIndex + 3, c: 0 }, e: { r: index + 3, c: 0 } };
59
+      repeatingData[item] = `A${index + 4}:A${itemIndex + 4}`;
25 60
     }
26 61
   });
27 62
   data.unshift(...name);
28
-  const ws = utils.aoa_to_sheet(data);
29
-  const wb = utils.book_new();
30
-  // 设置单元格样式
31
-  const cellRef = utils.encode_cell({ c: 0, r: 0 });
32
-  const cell = ws[cellRef];
33
-  if (!cell.s) cell.s = {};
34
-  cell.s.alignment = {
35
-    horizontal: "center",
36
-    vertical: "center"
37
-  };
38
-  const merges: Range[] = [];
39
-  Object.keys(repeatingData).forEach((item) => {
40
-    merges.push(repeatingData[item]);
63
+
64
+  const workbook = new Workbook();
65
+  workbook.created = new Date();
66
+
67
+  const worksheet = workbook.addWorksheet(fileName, { views: [{ state: "frozen", xSplit: 2, ySplit: 3 }] });
68
+  worksheet.addRows(data);
69
+  for (let i = 0; i < data.length; i++) {
70
+    worksheet.getRow(i + 1).alignment = { vertical: "middle", horizontal: "center" };
71
+  }
72
+  for (let i = 0; i < data[0].length; i++) {
73
+    worksheet.getColumn(i + 1).width = 20;
74
+  }
75
+  for (let i = 0; i < 3; i++) {
76
+    worksheet.getRow(i + 1).font = { bold: true };
77
+    worksheet.getRow(i + 1).border = {
78
+      top: { style: "thick", color: { argb: "000000" } },
79
+      left: { style: "thick", color: { argb: "000000" } },
80
+      bottom: { style: "thick", color: { argb: "000000" } },
81
+      right: { style: "thick", color: { argb: "000000" } }
82
+    };
83
+  }
84
+  for (let i = 0; i < 2; i++) {
85
+    worksheet.getColumn(i + 1).font = { bold: true };
86
+    worksheet.getColumn(i + 1).border = {
87
+      top: { style: "thick", color: { argb: "000000" } },
88
+      left: { style: "thick", color: { argb: "000000" } },
89
+      bottom: { style: "thick", color: { argb: "000000" } },
90
+      right: { style: "thick", color: { argb: "000000" } }
91
+    };
92
+  }
93
+  worksheet.mergeCells("A1:A3");
94
+  worksheet.mergeCells("B1:B3");
95
+  worksheet.mergeCells("A4:B4");
96
+  worksheet.mergeCells(`${computedCol(data[0].length - 1)}1:${computedCol(data[0].length - 1)}3`);
97
+  worksheet.mergeCells(`${computedCol(data[0].length - 2)}1:${computedCol(data[0].length - 2)}3`);
98
+  Object.keys(repeatingData).forEach((key) => {
99
+    worksheet.mergeCells(repeatingData[key]);
100
+  });
101
+  workbook.xlsx.writeBuffer().then((res) => {
102
+    const blob = new Blob([res]);
103
+    const a = document.createElement("a");
104
+    a.style.display = "none";
105
+    a.download = decodeURI(`${fileName}.xlsx`);
106
+    try {
107
+      a.href = window.URL.createObjectURL(blob);
108
+    } catch (err) {
109
+      console.warn("暂无文件信息.请通知开发人员导入文件模版");
110
+    }
111
+    a.click();
112
+    a.remove();
41 113
   });
42
-  ws["!merges"] = [
43
-    { s: { r: 0, c: 0 }, e: { r: 2, c: 0 } },
44
-    { s: { r: 0, c: 1 }, e: { r: 2, c: 1 } },
45
-    { s: { r: 3, c: 0 }, e: { r: 3, c: 1 } },
46
-    ...merges
47
-  ];
48
-  utils.book_append_sheet(wb, ws, fileName);
49
-  writeFile(wb, `${fileName}.xlsx`);
50
-  // console.log(cellRef, cell);
51 114
 };

+ 51 - 0
src/components/export2xlsx/index1.ts

@@ -0,0 +1,51 @@
1
+import type { Range } from "xlsx";
2
+import { writeFile, utils } from "xlsx";
3
+
4
+export const exportExcel = (fileData: any[], headerName: any[], headerProp: string[], fileName: string) => {
5
+  // console.log(fileData, headerName, headerProp, fileName);
6
+  const repeatingData: any = {};
7
+  const name: string[][] = [[], [], []];
8
+  const data = fileData.map((obj) => {
9
+    return headerProp.map((prop) => obj[prop]);
10
+  });
11
+  name[0].push("省份", "储备仓库", ...headerName.map((item) => item.matypename2));
12
+  name[1].push("省份", "储备仓库", ...headerName.map((item) => item.matypename3));
13
+  name[2].push("省份", "储备仓库", ...headerName.map((item) => item.matypename4));
14
+  name[0].forEach((item, index) => {
15
+    const itemIndex = name[0].findIndex((ite) => ite === item);
16
+    if (itemIndex !== index) {
17
+      repeatingData[item] = { s: { r: 0, c: itemIndex }, e: { r: 0, c: index } };
18
+    }
19
+  });
20
+  const cols = data.map((item) => item[0]);
21
+  cols.forEach((item, index) => {
22
+    const itemIndex = cols.findIndex((ite) => ite === item);
23
+    if (itemIndex !== index) {
24
+      repeatingData[item] = { s: { r: itemIndex + 3, c: 0 }, e: { r: index + 3, c: 0 } };
25
+    }
26
+  });
27
+  data.unshift(...name);
28
+  const ws = utils.aoa_to_sheet(data);
29
+  const wb = utils.book_new();
30
+  // 设置单元格样式
31
+  const cellRef = utils.encode_cell({ c: 0, r: 0 });
32
+  const cell = ws[cellRef];
33
+  if (!cell.s) cell.s = {};
34
+  cell.s.alignment = {
35
+    horizontal: "center",
36
+    vertical: "center"
37
+  };
38
+  const merges: Range[] = [];
39
+  Object.keys(repeatingData).forEach((item) => {
40
+    merges.push(repeatingData[item]);
41
+  });
42
+  ws["!merges"] = [
43
+    { s: { r: 0, c: 0 }, e: { r: 2, c: 0 } },
44
+    { s: { r: 0, c: 1 }, e: { r: 2, c: 1 } },
45
+    { s: { r: 3, c: 0 }, e: { r: 3, c: 1 } },
46
+    ...merges
47
+  ];
48
+  utils.book_append_sheet(wb, ws, fileName);
49
+  writeFile(wb, `${fileName}.xlsx`);
50
+  // console.log(cellRef, cell);
51
+};

+ 2 - 2
src/utils/util.ts

@@ -1,4 +1,4 @@
1
-import { ref, toRef } from "vue";
1
+import { ref } from "vue";
2 2
 import CryptoJS from "crypto-js";
3 3
 
4 4
 // 构造树型结构数据
@@ -13,7 +13,7 @@ export function handleTree(arr: any, id: string) {
13 13
   function turnTree(arr: any, id: string) {
14 14
     const tree = ref<any>([]);
15 15
     for (let i = 0; i < arr.length; i++) {
16
-      const isFirst = tree.value.findIndex((item: any) => arr[i][id].includes(item[id]));
16
+      const isFirst = tree.value.findIndex((item: any) => arr[i][id].slice(0, 3) === item[id]);
17 17
       if (isFirst !== -1) {
18 18
         tree.value[isFirst].children.push(arr[i]);
19 19
       } else {

+ 245 - 0
src/views/dataStatistics/components/detailedTable.vue

@@ -0,0 +1,245 @@
1
+<template>
2
+  <basic-container>
3
+    <el-form class="whole_form">
4
+      <el-row :gutter="20">
5
+        <el-col :span="6" v-if="userInfo.deptType === '1'">
6
+          <el-form-item label="省份">
7
+            <el-select v-model="searchList.gameDeptId" multiple clearable @change="getSupplies">
8
+              <el-option v-for="item in cityList" :key="item.deptId" :label="item.name" :value="item.deptId" />
9
+            </el-select>
10
+          </el-form-item>
11
+        </el-col>
12
+        <el-col :span="6" v-if="userInfo.deptType === '1'">
13
+          <el-form-item label="储备仓库">
14
+            <el-select
15
+              multiple
16
+              clearable
17
+              v-model="searchList.warehouseDeptId"
18
+              :disabled="!searchList.gameDeptId"
19
+              :placeholder="!searchList.gameDeptId ? '请先选择省份' : '请选择储备仓库'"
20
+            >
21
+              <el-option
22
+                v-for="item in warehouseList"
23
+                :key="item.deptId"
24
+                :label="item.abbreviationName"
25
+                :value="item.deptId"
26
+              />
27
+            </el-select>
28
+          </el-form-item>
29
+        </el-col>
30
+        <el-col :span="6" v-if="userInfo.deptType === '2'">
31
+          <el-form-item label="储备仓库">
32
+            <el-select v-model="searchList.warehouseDeptId" multiple clearable placeholder="请选择储备仓库">
33
+              <el-option
34
+                v-for="item in warehouseList"
35
+                :key="item.deptId"
36
+                :label="item.abbreviationName"
37
+                :value="item.deptId"
38
+              />
39
+            </el-select>
40
+          </el-form-item>
41
+        </el-col>
42
+        <el-col :span="6">
43
+          <el-form-item label="物资类别">
44
+            <el-select v-model="searchList.dmUpcode1List" clearable multiple>
45
+              <el-option v-for="item in suppliesList" :key="item.id" :label="item.name" :value="item.code" />
46
+            </el-select>
47
+          </el-form-item>
48
+        </el-col>
49
+        <el-col :span="6">
50
+          <el-form-item label="物资名称">
51
+            <el-input v-model="searchList.dmUpname2" clearable />
52
+          </el-form-item>
53
+        </el-col>
54
+      </el-row>
55
+      <el-row class="btn_center">
56
+        <el-button :icon="Search" type="primary" @click="getList">查询</el-button>
57
+        <el-button :icon="RefreshRight" @click="clearSearch">清空</el-button>
58
+      </el-row>
59
+    </el-form>
60
+
61
+    <el-table
62
+      :data="tableData"
63
+      stripe
64
+      border
65
+      style="height: 80%"
66
+      :span-method="arraySpanMethod"
67
+      v-loading="tableLoading"
68
+    >
69
+      <!-- <el-table :data="tableData" stripe border> -->
70
+      <el-table-column fixed type="index" label="序号" header-align="center" align="center" />
71
+      <el-table-column fixed prop="gameName" label="省份" header-align="center" align="center" />
72
+      <el-table-column fixed prop="warehouseName" label="储备仓库" header-align="center" align="center" width="120" />
73
+      <el-table-column fixed prop="materials1" label="物资大类" header-align="center" align="center" />
74
+      <el-table-column prop="materials2" label="物资类别" header-align="center" align="center" />
75
+      <el-table-column prop="materials3" label="物资名称" header-align="center" align="center" />
76
+      <el-table-column prop="materials4" label="物资单位" header-align="center" align="center" />
77
+      <el-table-column prop="specs" label="规格" header-align="center" align="center" />
78
+      <el-table-column prop="quantity" label="数量" header-align="center" align="center" />
79
+      <el-table-column prop="inboundTime" label="入库时间" header-align="center" align="center" />
80
+      <el-table-column prop="unitPrice" label="单价(元)" header-align="center" align="center" />
81
+      <el-table-column prop="totalPrice" label="总价(万元)" header-align="center" align="center">
82
+        <template #default="{ row }">
83
+          {{ row.totalPrice ?? row.warehouseTotalPrice }}
84
+        </template>
85
+      </el-table-column>
86
+      <el-table-column prop="remarks" label="备注" header-align="center" align="center" />
87
+    </el-table>
88
+  </basic-container>
89
+</template>
90
+
91
+<script setup lang="ts">
92
+import { ref } from "vue";
93
+
94
+import { useGetters } from "@/hooks/storeHooks";
95
+import { Search, RefreshRight } from "@element-plus/icons-vue";
96
+import { getDetailList, getCityList, getSysTreeDict } from "@/api/dataStatistics/index";
97
+
98
+const tableData: any = ref([]);
99
+const tableLoading = ref(false);
100
+const searchList: any = ref({
101
+  gameDeptId: [],
102
+  warehouseDeptId: [],
103
+  dmUpcode1List: [],
104
+  dmUpname2: ""
105
+});
106
+const mergeObj: any = ref({});
107
+const cityList: any = ref([]);
108
+const warehouseList: any = ref([]);
109
+const suppliesList: any = ref([]);
110
+
111
+const { userInfo } = useGetters(["userInfo"]);
112
+const props = defineProps({
113
+  payload: {
114
+    type: Array,
115
+    default: () => []
116
+  }
117
+});
118
+
119
+if (userInfo.value.deptType === "1") {
120
+  // 获取省份列表
121
+  getCityList({ deptType: 2 }).then((res: any) => {
122
+    if (res.code === 0) {
123
+      cityList.value = res.data;
124
+      searchList.value.gameDeptId = [cityList.value[0].deptId];
125
+      getSupplies(searchList.value.gameDeptId);
126
+      getList();
127
+    }
128
+  });
129
+} else {
130
+  // 获取储备仓库
131
+  getCityList({ parentIdList: [userInfo.value.deptId] }).then((res: any) => {
132
+    if (res.code === 0) {
133
+      warehouseList.value = res.data;
134
+      searchList.value.warehouseDeptId = [warehouseList.value[0].deptId];
135
+      getList();
136
+    }
137
+  });
138
+}
139
+
140
+// 根据省份列表获取储备仓库
141
+const getSupplies = (value: string) => {
142
+  getCityList({ parentIdList: value }).then((res: any) => {
143
+    if (res.code === 0) {
144
+      warehouseList.value = res.data;
145
+    }
146
+  });
147
+};
148
+
149
+// 获取物资类别
150
+getSysTreeDict({ type: 1, difference: 2, parentCodeList: props.payload }).then((res: any) => {
151
+  if (res.code === 0) {
152
+    suppliesList.value = res.data;
153
+  }
154
+});
155
+
156
+const clearSearch = () => {
157
+  searchList.value = {
158
+    gameDeptId: [],
159
+    warehouseDeptId: [],
160
+    dmUpcode1List: [],
161
+    dmUpname2: ""
162
+  };
163
+  getList();
164
+};
165
+
166
+// 获取表格数据
167
+const getList = () => {
168
+  const data = {
169
+    dmUpcode0List: props.payload,
170
+    ...searchList.value
171
+  };
172
+  tableLoading.value = true;
173
+  getDetailList(data).then((res: any) => {
174
+    if (res.code === 0) {
175
+      tableData.value = res.data.filter((item: any) => {
176
+        if (item.gameName === null && item.totalPrice === null) {
177
+          item.unitPrice = "总价值";
178
+          return item;
179
+        } else if (item.totalPrice === null) {
180
+          item.unitPrice = "合计";
181
+          return item;
182
+        } else {
183
+          return item;
184
+        }
185
+      });
186
+      getSpanArr(tableData.value);
187
+    }
188
+  });
189
+};
190
+
191
+const arraySpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
192
+  const firstHidden = [2, 3, 4, 5, 6, 7, 8, 9];
193
+  const secondHidden = [4, 5, 6, 7, 8, 9];
194
+  if (rowIndex === 0) {
195
+    if (columnIndex === 1) {
196
+      return [1, 9];
197
+    } else if (firstHidden.includes(columnIndex)) {
198
+      return [0, 0];
199
+    }
200
+  } else if (row.unitPrice === "合计") {
201
+    if (columnIndex === 3) {
202
+      return [1, 7];
203
+    } else if (secondHidden.includes(columnIndex)) {
204
+      return [0, 0];
205
+    }
206
+  }
207
+  const mergeCol = ["gameName", "warehouseName", "materials1", "materials2"];
208
+  // 判断列的属性
209
+  if (mergeCol.indexOf(column.property) !== -1) {
210
+    // 判断其值是不是为0
211
+    if (mergeObj.value[column.property][rowIndex]) {
212
+      return [mergeObj.value[column.property][rowIndex], 1];
213
+    } else {
214
+      // 如果为0则为需要合并的行
215
+      return [0, 0];
216
+    }
217
+  }
218
+};
219
+
220
+// getSpanArr方法
221
+const getSpanArr = (data: any) => {
222
+  const mergeCol = ["gameName", "warehouseName", "materials1", "materials2"];
223
+  mergeCol.forEach((key: any) => {
224
+    let count = 0; // 用来记录需要合并行的起始位置
225
+    mergeObj.value[key] = []; // 记录每一列的合并信息
226
+    data.forEach((item: any, index: number) => {
227
+      // index == 0表示数据为第一行,直接 push 一个 1
228
+      if (index === 0) {
229
+        mergeObj.value[key].push(1);
230
+      } else {
231
+        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
232
+        if (item[key] === data[index - 1][key]) {
233
+          mergeObj.value[key][count] += 1;
234
+          mergeObj.value[key].push(0);
235
+        } else {
236
+          // 如果当前行和上一行其值不相等
237
+          count = index; // 记录当前位置
238
+          mergeObj.value[key].push(1); // 重新push 一个 1
239
+        }
240
+      }
241
+    });
242
+  });
243
+  tableLoading.value = false;
244
+};
245
+</script>

+ 285 - 0
src/views/dataStatistics/components/valueTable.vue

@@ -0,0 +1,285 @@
1
+<template>
2
+  <basic-container>
3
+    <el-form class="whole_form">
4
+      <el-row :gutter="20">
5
+        <el-col :span="6" v-if="userInfo.deptType === '1'">
6
+          <el-form-item label="省份">
7
+            <el-select v-model="searchList.provinceDeptIdList" clearable multiple @change="getSupplies">
8
+              <el-option v-for="item in cityList" :key="item.deptId" :label="item.name" :value="item.deptId" />
9
+            </el-select>
10
+          </el-form-item>
11
+        </el-col>
12
+        <el-col :span="6" v-if="userInfo.deptType === '1'">
13
+          <el-form-item label="储备仓库">
14
+            <el-select
15
+              v-model="searchList.deptIdList"
16
+              clearable
17
+              multiple
18
+              :disabled="searchList.provinceDeptIdList.length === 0"
19
+              :placeholder="searchList.provinceDeptIdList.length === 0 ? '请先选择省份' : '请选择储备仓库'"
20
+            >
21
+              <el-option
22
+                v-for="item in warehouseList"
23
+                :key="item.deptId"
24
+                :label="item.abbreviationName"
25
+                :value="item.deptId"
26
+              />
27
+            </el-select>
28
+          </el-form-item>
29
+        </el-col>
30
+        <el-col :span="6" v-if="userInfo.deptType === '2'">
31
+          <el-form-item label="储备仓库">
32
+            <el-select v-model="searchList.deptIdList" clearable multiple placeholder="请选择储备仓库">
33
+              <el-option
34
+                v-for="item in warehouseList"
35
+                :key="item.deptId"
36
+                :label="item.abbreviationName"
37
+                :value="item.deptId"
38
+              />
39
+            </el-select>
40
+          </el-form-item>
41
+        </el-col>
42
+        <el-col :span="6">
43
+          <el-form-item label="物资类别">
44
+            <el-select v-model="searchList.dmUpcode1List" clearable multiple>
45
+              <el-option v-for="item in suppliesList" :key="item.id" :label="item.name" :value="item.code" />
46
+            </el-select>
47
+          </el-form-item>
48
+        </el-col>
49
+        <el-col :span="6">
50
+          <el-form-item label="物资名称">
51
+            <el-input v-model="searchList.dmUpname2" clearable />
52
+          </el-form-item>
53
+        </el-col>
54
+      </el-row>
55
+      <el-row class="btn_center">
56
+        <el-button :icon="Search" type="primary" @click="getList">查询</el-button>
57
+        <el-button :icon="RefreshRight" @click="clearSearch">清空</el-button>
58
+      </el-row>
59
+    </el-form>
60
+
61
+    <el-button type="primary" :icon="Download" style="margin-bottom: 10px" @click="downloadExcel">导出</el-button>
62
+    <el-table
63
+      :data="tableData"
64
+      stripe
65
+      border
66
+      style="height: 80%"
67
+      v-loading="tableLoading"
68
+      :span-method="arraySpanMethod"
69
+    >
70
+      <el-table-column fixed type="index" label="序号" header-align="center" align="center" />
71
+      <el-table-column fixed prop="upidName" label="省份" header-align="center" align="center" />
72
+      <el-table-column fixed prop="username" label="储备仓库" header-align="center" align="center" width="120" />
73
+      <template v-for="item in headerName" :key="item">
74
+        <el-table-column :label="item.dmUpname" header-align="center" align="center">
75
+          <template v-for="iten in item.children" :key="iten">
76
+            <el-table-column :label="iten.dmUpname" header-align="center" align="center">
77
+              <el-table-column :prop="iten.dmUpcode" :label="iten.units" header-align="center" align="center" />
78
+            </el-table-column>
79
+          </template>
80
+        </el-table-column>
81
+      </template>
82
+      <el-table-column prop="tolNum" label="数量总计(件)" header-align="center" align="center" />
83
+      <el-table-column prop="tolMoney" label="总价值(万元)" header-align="center" align="center" />
84
+    </el-table>
85
+  </basic-container>
86
+</template>
87
+
88
+<script setup lang="ts">
89
+import { ref } from "vue";
90
+
91
+import { deepClone, handleTree } from "@/utils/util";
92
+import { useGetters } from "@/hooks/storeHooks";
93
+import { exportExcel } from "@/components/export2xlsx";
94
+import {
95
+  getDroughtResistantHeader,
96
+  getDroughtResistantList,
97
+  getCityList,
98
+  getSysTreeDict
99
+} from "@/api/dataStatistics/index";
100
+import { Search, RefreshRight, Download } from "@element-plus/icons-vue";
101
+
102
+const headerName: any = ref([]);
103
+const headerProps: any = ref([]);
104
+const tableData: any = ref([]);
105
+const searchList: any = ref({
106
+  provinceDeptIdList: [],
107
+  deptIdList: [],
108
+  dmUpcode1List: [],
109
+  dmUpname2: ""
110
+});
111
+const mergeObj: any = ref({});
112
+const cityList: any = ref([]);
113
+const warehouseList: any = ref([]);
114
+const suppliesList: any = ref([]);
115
+const tableLoading = ref(false);
116
+const exportHeaderName = ref([]); // 导出用表头
117
+
118
+const { userInfo } = useGetters(["userInfo"]);
119
+
120
+const props = defineProps({
121
+  payload: {
122
+    type: Array,
123
+    default: () => []
124
+  },
125
+  fileName: {
126
+    type: String,
127
+    default: ""
128
+  }
129
+});
130
+
131
+if (userInfo.value.deptType === "1") {
132
+  // 获取省份列表
133
+  getCityList({ deptType: 2 }).then((res: any) => {
134
+    if (res.code === 0) {
135
+      cityList.value = res.data;
136
+    }
137
+  });
138
+} else {
139
+  // 获取储备仓库
140
+  getCityList({ parentIdList: [userInfo.value.deptId] }).then((res: any) => {
141
+    if (res.code === 0) {
142
+      warehouseList.value = res.data;
143
+    }
144
+  });
145
+}
146
+
147
+// 根据省份列表获取储备仓库
148
+const getSupplies = (value: string[]) => {
149
+  getCityList({ parentIdList: value }).then((res: any) => {
150
+    if (res.code === 0) {
151
+      warehouseList.value = res.data;
152
+    }
153
+  });
154
+};
155
+
156
+// 获取物资类别
157
+getSysTreeDict({ type: 1, difference: 2, parentCodeList: props.payload }).then((res: any) => {
158
+  if (res.code === 0) {
159
+    suppliesList.value = res.data;
160
+  }
161
+});
162
+
163
+// 获取表头数据
164
+getDroughtResistantHeader({ matype1: props.payload }).then((res: any) => {
165
+  if (res.code === 0) {
166
+    res.data
167
+      .map((item: any) => {
168
+        const parent = {
169
+          dmUpcode: item.matypecode2,
170
+          dmUpname: item.matypename2
171
+        };
172
+        const own = {
173
+          dmUpcode: item.matypecode3,
174
+          dmUpname: item.matypename3,
175
+          units: item.matypename4
176
+        };
177
+        return [parent, own];
178
+      })
179
+      .forEach((item: any) => {
180
+        headerName.value.push(...item);
181
+      });
182
+    exportHeaderName.value = res.data;
183
+    headerName.value = handleTree(headerName.value, "dmUpcode");
184
+    headerProps.value = res.data.map((item: any) => item.matypecode3);
185
+    headerProps.value.unshift("upidName", "username");
186
+  }
187
+  getList();
188
+});
189
+
190
+const clearSearch = () => {
191
+  searchList.value = {
192
+    provinceDeptIdList: [],
193
+    deptIdList: [],
194
+    dmUpcode1List: [],
195
+    dmUpname2: ""
196
+  };
197
+  getList();
198
+};
199
+
200
+// getSpanArr方法
201
+const getSpanArr = (data: any) => {
202
+  const mergeCol = ["upidName", "username"];
203
+  mergeCol.forEach((key: any) => {
204
+    let count = 0; // 用来记录需要合并行的起始位置
205
+    mergeObj.value[key] = []; // 记录每一列的合并信息
206
+    data.forEach((item: any, index: number) => {
207
+      // index == 0表示数据为第一行,直接 push 一个 1
208
+      if (index === 0) {
209
+        mergeObj.value[key].push(1);
210
+      } else {
211
+        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
212
+        if (item[key] === data[index - 1][key]) {
213
+          mergeObj.value[key][count] += 1;
214
+          mergeObj.value[key].push(0);
215
+        } else {
216
+          // 如果当前行和上一行其值不相等
217
+          count = index; // 记录当前位置
218
+          mergeObj.value[key].push(1); // 重新push 一个 1
219
+        }
220
+      }
221
+    });
222
+  });
223
+  tableLoading.value = false;
224
+};
225
+
226
+// 获取表格数据
227
+const getList = () => {
228
+  const data = {
229
+    ...searchList.value,
230
+    dmUpcode0List: ["100", "200"]
231
+  };
232
+  tableLoading.value = true;
233
+  getDroughtResistantList(data).then((res: any) => {
234
+    if (res.code === 0) {
235
+      tableData.value = res.data
236
+        .map((item: any) => {
237
+          const retVal: any = ref({
238
+            ...item.map
239
+          });
240
+          retVal.value.upidName = item.upidName;
241
+          retVal.value.username = item.username;
242
+          retVal.value.tolNum = item.tolNum;
243
+          retVal.value.tolMoney = item.tolMoney;
244
+          return retVal.value;
245
+        })
246
+        .filter((item: any) => {
247
+          headerProps.value.filter((ite: any) => {
248
+            if (!item[ite]) {
249
+              item[ite] = 0;
250
+            }
251
+          });
252
+          return item;
253
+        });
254
+      getSpanArr(tableData.value);
255
+    }
256
+  });
257
+};
258
+
259
+const arraySpanMethod = ({ column, rowIndex, columnIndex }: any) => {
260
+  if (rowIndex === 0) {
261
+    if (columnIndex === 1) {
262
+      return [1, 2];
263
+    } else if (columnIndex === 2) {
264
+      return [0, 0];
265
+    }
266
+  }
267
+  const mergeCol = ["upidName", "username"];
268
+  // 判断列的属性
269
+  if (mergeCol.indexOf(column.property) !== -1) {
270
+    // 判断其值是不是为0
271
+    if (mergeObj.value[column.property][rowIndex]) {
272
+      return [mergeObj.value[column.property][rowIndex], 1];
273
+    } else {
274
+      // 如果为0则为需要合并的行
275
+      return [0, 0];
276
+    }
277
+  }
278
+};
279
+
280
+const downloadExcel = () => {
281
+  const exportProp = deepClone(headerProps.value);
282
+  exportProp.push("tolNum", "tolMoney");
283
+  exportExcel(tableData.value, exportHeaderName.value, exportProp, props.fileName);
284
+};
285
+</script>

+ 2 - 258
src/views/dataStatistics/droughtResistant/index.vue

@@ -1,264 +1,8 @@
1 1
 <!-- 防汛抗旱物资数量价值表 -->
2 2
 <template>
3
-  <basic-container>
4
-    <el-form class="whole_form">
5
-      <el-row :gutter="20">
6
-        <el-col :span="6" v-if="userInfo.deptType === '1'">
7
-          <el-form-item label="省份">
8
-            <el-select v-model="searchList.provinceDeptIdList" clearable multiple @change="getSupplies">
9
-              <el-option v-for="item in cityList" :key="item.deptId" :label="item.name" :value="item.deptId" />
10
-            </el-select>
11
-          </el-form-item>
12
-        </el-col>
13
-        <el-col :span="6" v-if="userInfo.deptType === '1'">
14
-          <el-form-item label="储备仓库">
15
-            <el-select
16
-              v-model="searchList.deptIdList"
17
-              clearable
18
-              multiple
19
-              :disabled="searchList.provinceDeptIdList.length === 0"
20
-              :placeholder="searchList.provinceDeptIdList.length === 0 ? '请先选择省份' : '请选择储备仓库'"
21
-            >
22
-              <el-option
23
-                v-for="item in warehouseList"
24
-                :key="item.deptId"
25
-                :label="item.abbreviationName"
26
-                :value="item.deptId"
27
-              />
28
-            </el-select>
29
-          </el-form-item>
30
-        </el-col>
31
-        <el-col :span="6" v-if="userInfo.deptType === '2'">
32
-          <el-form-item label="储备仓库">
33
-            <el-select v-model="searchList.deptIdList" clearable multiple placeholder="请选择储备仓库">
34
-              <el-option
35
-                v-for="item in warehouseList"
36
-                :key="item.deptId"
37
-                :label="item.abbreviationName"
38
-                :value="item.deptId"
39
-              />
40
-            </el-select>
41
-          </el-form-item>
42
-        </el-col>
43
-        <el-col :span="6">
44
-          <el-form-item label="物资类别">
45
-            <el-select v-model="searchList.dmUpcode1List" clearable multiple>
46
-              <el-option v-for="item in suppliesList" :key="item.id" :label="item.name" :value="item.code" />
47
-            </el-select>
48
-          </el-form-item>
49
-        </el-col>
50
-        <el-col :span="6">
51
-          <el-form-item label="物资名称">
52
-            <el-input v-model="searchList.dmUpname2" clearable />
53
-          </el-form-item>
54
-        </el-col>
55
-      </el-row>
56
-      <el-row class="btn_center">
57
-        <el-button :icon="Search" type="primary" @click="getList">查询</el-button>
58
-        <el-button :icon="RefreshRight" @click="clearSearch">清空</el-button>
59
-      </el-row>
60
-    </el-form>
61
-
62
-    <el-button type="primary" :icon="Download" style="margin-bottom: 10px" @click="downloadExcel">导出</el-button>
63
-    <el-table :data="tableData" stripe border :span-method="arraySpanMethod">
64
-      <el-table-column type="index" label="序号" header-align="center" align="center" />
65
-      <el-table-column prop="upidName" label="省份" header-align="center" align="center" />
66
-      <el-table-column prop="username" label="储备仓库" header-align="center" align="center" width="120" />
67
-      <template v-for="item in headerName" :key="item">
68
-        <el-table-column :label="item.dmUpname" header-align="center" align="center">
69
-          <template v-for="iten in item.children" :key="iten">
70
-            <el-table-column :label="iten.dmUpname" header-align="center" align="center">
71
-              <el-table-column :prop="iten.dmUpcode" :label="iten.units" header-align="center" align="center" />
72
-            </el-table-column>
73
-          </template>
74
-        </el-table-column>
75
-      </template>
76
-      <el-table-column prop="tolNum" label="数量总计(件)" header-align="center" align="center" />
77
-      <el-table-column prop="tolMoney" label="总价值(万元)" header-align="center" align="center" />
78
-    </el-table>
79
-  </basic-container>
3
+  <valueTable :payload="['100', '200']" fileName="防汛抗旱物资数量价值表" />
80 4
 </template>
81 5
 
82 6
 <script setup lang="ts">
83
-import { ref } from "vue";
84
-
85
-import { handleTree } from "@/utils/util";
86
-import { useGetters } from "@/hooks/storeHooks";
87
-import { exportExcel } from "@/components/export2xlsx";
88
-import {
89
-  getDroughtResistantHeader,
90
-  getDroughtResistantList,
91
-  getCityList,
92
-  getSysTreeDict
93
-} from "@/api/dataStatistics/index";
94
-import { Search, RefreshRight, Download } from "@element-plus/icons-vue";
95
-
96
-const headerName: any = ref([]);
97
-const headerProps: any = ref([]);
98
-const tableData: any = ref([]);
99
-const searchList: any = ref({
100
-  provinceDeptIdList: [],
101
-  deptIdList: [],
102
-  dmUpcode1List: [],
103
-  dmUpname2: ""
104
-});
105
-const mergeObj: any = ref({});
106
-const cityList: any = ref([]);
107
-const warehouseList: any = ref([]);
108
-const suppliesList: any = ref([]);
109
-const exportHeaderName = ref([]); // 导出用表头
110
-
111
-const { userInfo } = useGetters(["userInfo"]);
112
-
113
-if (userInfo.value.deptType === "1") {
114
-  // 获取省份列表
115
-  getCityList({ deptType: 2 }).then((res: any) => {
116
-    if (res.code === 0) {
117
-      cityList.value = res.data;
118
-    }
119
-  });
120
-} else {
121
-  // 获取储备仓库
122
-  getCityList({ parentIdList: [userInfo.value.deptId] }).then((res: any) => {
123
-    if (res.code === 0) {
124
-      warehouseList.value = res.data;
125
-    }
126
-  });
127
-}
128
-
129
-// 根据省份列表获取储备仓库
130
-const getSupplies = (value: string[]) => {
131
-  getCityList({ parentIdList: value }).then((res: any) => {
132
-    if (res.code === 0) {
133
-      warehouseList.value = res.data;
134
-    }
135
-  });
136
-};
137
-
138
-// 获取物资类别
139
-getSysTreeDict({ type: 1, difference: 2, parentCodeList: ["100", "200"] }).then((res: any) => {
140
-  if (res.code === 0) {
141
-    suppliesList.value = res.data;
142
-  }
143
-});
144
-
145
-// 获取表头数据
146
-getDroughtResistantHeader({ matype1: ["100", "200"] }).then((res: any) => {
147
-  if (res.code === 0) {
148
-    res.data
149
-      .map((item: any) => {
150
-        const parent = {
151
-          dmUpcode: item.matypecode2,
152
-          dmUpname: item.matypename2
153
-        };
154
-        const own = {
155
-          dmUpcode: item.matypecode3,
156
-          dmUpname: item.matypename3,
157
-          units: item.matypename4
158
-        };
159
-        return [parent, own];
160
-      })
161
-      .forEach((item: any) => {
162
-        headerName.value.push(...item);
163
-      });
164
-    exportHeaderName.value = res.data;
165
-    headerName.value = handleTree(headerName.value, "dmUpcode");
166
-    headerProps.value = res.data.map((item: any) => item.matypecode3);
167
-    headerProps.value.unshift("upidName", "username");
168
-  }
169
-  getList();
170
-});
171
-
172
-const clearSearch = () => {
173
-  searchList.value = {
174
-    provinceDeptIdList: [],
175
-    deptIdList: [],
176
-    dmUpcode1List: [],
177
-    dmUpname2: ""
178
-  };
179
-  getList();
180
-};
181
-
182
-// getSpanArr方法
183
-const getSpanArr = (data: any) => {
184
-  const mergeCol = ["upidName", "username"];
185
-  // headerProps.value.forEach((key: any) => {
186
-  mergeCol.forEach((key: any) => {
187
-    let count = 0; // 用来记录需要合并行的起始位置
188
-    mergeObj.value[key] = []; // 记录每一列的合并信息
189
-    data.forEach((item: any, index: number) => {
190
-      // index == 0表示数据为第一行,直接 push 一个 1
191
-      if (index === 0) {
192
-        mergeObj.value[key].push(1);
193
-      } else {
194
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
195
-        if (item[key] === data[index - 1][key]) {
196
-          mergeObj.value[key][count] += 1;
197
-          mergeObj.value[key].push(0);
198
-        } else {
199
-          // 如果当前行和上一行其值不相等
200
-          count = index; // 记录当前位置
201
-          mergeObj.value[key].push(1); // 重新push 一个 1
202
-        }
203
-      }
204
-    });
205
-  });
206
-};
207
-
208
-// 获取表格数据
209
-const getList = () => {
210
-  const data = {
211
-    ...searchList.value,
212
-    dmUpcode0List: ["100", "200"]
213
-  };
214
-  getDroughtResistantList(data).then((res: any) => {
215
-    if (res.code === 0) {
216
-      tableData.value = res.data
217
-        .map((item: any) => {
218
-          const retVal: any = ref({
219
-            ...item.map
220
-          });
221
-          retVal.value.upidName = item.upidName;
222
-          retVal.value.username = item.username;
223
-          retVal.value.tolNum = item.tolNum;
224
-          retVal.value.tolMoney = item.tolMoney;
225
-          return retVal.value;
226
-        })
227
-        .filter((item: any) => {
228
-          headerProps.value.filter((ite: any) => {
229
-            if (!item[ite]) {
230
-              item[ite] = 0;
231
-            }
232
-          });
233
-          return item;
234
-        });
235
-      getSpanArr(tableData.value);
236
-    }
237
-  });
238
-};
239
-
240
-const arraySpanMethod = ({ column, rowIndex, columnIndex }: any) => {
241
-  if (rowIndex === 0) {
242
-    if (columnIndex === 1) {
243
-      return [1, 2];
244
-    } else if (columnIndex === 2) {
245
-      return [0, 0];
246
-    }
247
-  }
248
-  const mergeCol = ["upidName", "username"];
249
-  // 判断列的属性
250
-  if (mergeCol.indexOf(column.property) !== -1) {
251
-    // 判断其值是不是为0
252
-    if (mergeObj.value[column.property][rowIndex]) {
253
-      return [mergeObj.value[column.property][rowIndex], 1];
254
-    } else {
255
-      // 如果为0则为需要合并的行
256
-      return [0, 0];
257
-    }
258
-  }
259
-};
260
-
261
-const downloadExcel = () => {
262
-  exportExcel(tableData.value, exportHeaderName.value, headerProps.value, "防汛抗旱物资数量价值表");
263
-};
7
+import valueTable from "@/views/dataStatistics/components/valueTable.vue";
264 8
 </script>

+ 4 - 227
src/views/dataStatistics/floodDroughtPrecaution/index.vue

@@ -1,233 +1,10 @@
1 1
 <!-- 防汛抗旱明细统计表 -->
2 2
 <template>
3
-  <basic-container>
4
-    <el-form class="whole_form">
5
-      <el-row :gutter="20">
6
-        <el-col :span="6" v-if="userInfo.deptType === '1'">
7
-          <el-form-item label="省份">
8
-            <el-select v-model="searchList.gameDeptId" multiple clearable @change="getSupplies">
9
-              <el-option v-for="item in cityList" :key="item.deptId" :label="item.name" :value="item.deptId" />
10
-            </el-select>
11
-          </el-form-item>
12
-        </el-col>
13
-        <el-col :span="6" v-if="userInfo.deptType === '1'">
14
-          <el-form-item label="储备仓库">
15
-            <el-select
16
-              multiple
17
-              clearable
18
-              v-model="searchList.warehouseDeptId"
19
-              :disabled="!searchList.gameDeptId"
20
-              :placeholder="!searchList.gameDeptId ? '请先选择省份' : '请选择储备仓库'"
21
-            >
22
-              <el-option
23
-                v-for="item in warehouseList"
24
-                :key="item.deptId"
25
-                :label="item.abbreviationName"
26
-                :value="item.deptId"
27
-              />
28
-            </el-select>
29
-          </el-form-item>
30
-        </el-col>
31
-        <el-col :span="6" v-if="userInfo.deptType === '2'">
32
-          <el-form-item label="储备仓库">
33
-            <el-select v-model="searchList.warehouseDeptId" multiple clearable placeholder="请选择储备仓库">
34
-              <el-option
35
-                v-for="item in warehouseList"
36
-                :key="item.deptId"
37
-                :label="item.abbreviationName"
38
-                :value="item.deptId"
39
-              />
40
-            </el-select>
41
-          </el-form-item>
42
-        </el-col>
43
-        <el-col :span="6">
44
-          <el-form-item label="物资类别">
45
-            <el-select v-model="searchList.dmUpcode1List" clearable multiple>
46
-              <el-option v-for="item in suppliesList" :key="item.id" :label="item.name" :value="item.code" />
47
-            </el-select>
48
-          </el-form-item>
49
-        </el-col>
50
-        <el-col :span="6">
51
-          <el-form-item label="物资名称">
52
-            <el-input v-model="searchList.dmUpname2" clearable />
53
-          </el-form-item>
54
-        </el-col>
55
-      </el-row>
56
-      <el-row class="btn_center">
57
-        <el-button :icon="Search" type="primary" @click="getList">查询</el-button>
58
-        <el-button :icon="RefreshRight" @click="clearSearch">清空</el-button>
59
-      </el-row>
60
-    </el-form>
61
-
62
-    <el-table :data="tableData" stripe border :span-method="arraySpanMethod" v-loading="tableLoading">
63
-      <!-- <el-table :data="tableData" stripe border> -->
64
-      <el-table-column type="index" label="序号" header-align="center" align="center" />
65
-      <el-table-column prop="gameName" label="省份" header-align="center" align="center" />
66
-      <el-table-column prop="warehouseName" label="储备仓库" header-align="center" align="center" width="120" />
67
-      <el-table-column prop="materials1" label="物资大类" header-align="center" align="center" />
68
-      <el-table-column prop="materials2" label="物资类别" header-align="center" align="center" />
69
-      <el-table-column prop="materials3" label="物资名称" header-align="center" align="center" />
70
-      <el-table-column prop="materials4" label="物资单位" header-align="center" align="center" />
71
-      <el-table-column prop="specs" label="规格" header-align="center" align="center" />
72
-      <el-table-column prop="quantity" label="数量" header-align="center" align="center" />
73
-      <el-table-column prop="inboundTime" label="入库时间" header-align="center" align="center" />
74
-      <el-table-column prop="unitPrice" label="单价(元)" header-align="center" align="center" />
75
-      <el-table-column prop="totalPrice" label="总价(万元)" header-align="center" align="center">
76
-        <template #default="{ row }">
77
-          {{ row.totalPrice ?? row.warehouseTotalPrice }}
78
-        </template>
79
-      </el-table-column>
80
-      <el-table-column prop="remarks" label="备注" header-align="center" align="center" />
81
-    </el-table>
82
-  </basic-container>
3
+  <detailedTable :payload="['100', '200']" />
83 4
 </template>
84 5
 
85 6
 <script setup lang="ts">
86
-import { ref } from "vue";
87
-
88
-import { useGetters } from "@/hooks/storeHooks";
89
-import { Search, RefreshRight } from "@element-plus/icons-vue";
90
-import { getDetailList, getCityList, getSysTreeDict } from "@/api/dataStatistics/index";
91
-
92
-const tableData: any = ref([]);
93
-const tableLoading = ref(false);
94
-const searchList: any = ref({
95
-  gameDeptId: [],
96
-  warehouseDeptId: [],
97
-  dmUpcode1List: [],
98
-  dmUpname2: ""
99
-});
100
-const mergeObj: any = ref({});
101
-const cityList: any = ref([]);
102
-const warehouseList: any = ref([]);
103
-const suppliesList: any = ref([]);
104
-
105
-const { userInfo } = useGetters(["userInfo"]);
106
-
107
-if (userInfo.value.deptType === "1") {
108
-  // 获取省份列表
109
-  getCityList({ deptType: 2 }).then((res: any) => {
110
-    if (res.code === 0) {
111
-      cityList.value = res.data;
112
-      searchList.value.gameDeptId = [cityList.value[0].deptId];
113
-      getSupplies(searchList.value.gameDeptId);
114
-    }
115
-  });
116
-} else {
117
-  // 获取储备仓库
118
-  getCityList({ parentIdList: [userInfo.value.deptId] }).then((res: any) => {
119
-    if (res.code === 0) {
120
-      warehouseList.value = res.data;
121
-      searchList.value.warehouseDeptId = [warehouseList.value[0].deptId];
122
-    }
123
-  });
124
-}
125
-
126
-// 根据省份列表获取储备仓库
127
-const getSupplies = (value: string) => {
128
-  getCityList({ parentIdList: value }).then((res: any) => {
129
-    if (res.code === 0) {
130
-      warehouseList.value = res.data;
131
-    }
132
-  });
133
-};
134
-
135
-// 获取物资类别
136
-getSysTreeDict({ type: 1, difference: 2, parentCodeList: ["100", "200"] }).then((res: any) => {
137
-  if (res.code === 0) {
138
-    suppliesList.value = res.data;
139
-  }
140
-});
141
-
142
-const clearSearch = () => {
143
-  searchList.value = {
144
-    gameDeptId: [],
145
-    warehouseDeptId: [],
146
-    dmUpcode1List: [],
147
-    dmUpname2: ""
148
-  };
149
-  getList();
150
-};
151
-
152
-// 获取表格数据
153
-const getList = () => {
154
-  const data = {
155
-    dmUpcode0List: ["100", "200"],
156
-    ...searchList.value
157
-  };
158
-  tableLoading.value = true;
159
-  getDetailList(data).then((res: any) => {
160
-    if (res.code === 0) {
161
-      tableData.value = res.data.filter((item: any) => {
162
-        if (item.gameName === null && item.totalPrice === null) {
163
-          item.unitPrice = "总价值";
164
-          return item;
165
-        } else if (item.totalPrice === null) {
166
-          item.unitPrice = "合计";
167
-          return item;
168
-        } else {
169
-          return item;
170
-        }
171
-      });
172
-      getSpanArr(tableData.value);
173
-    }
174
-  });
175
-};
176
-
177
-getList();
178
-
179
-const arraySpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
180
-  const firstHidden = [2, 3, 4, 5, 6, 7, 8, 9];
181
-  const secondHidden = [4, 5, 6, 7, 8, 9];
182
-  if (rowIndex === 0) {
183
-    if (columnIndex === 1) {
184
-      return [1, 9];
185
-    } else if (firstHidden.includes(columnIndex)) {
186
-      return [0, 0];
187
-    }
188
-  } else if (row.unitPrice === "合计") {
189
-    if (columnIndex === 3) {
190
-      return [1, 7];
191
-    } else if (secondHidden.includes(columnIndex)) {
192
-      return [0, 0];
193
-    }
194
-  }
195
-  const mergeCol = ["gameName", "warehouseName", "materials1", "materials2"];
196
-  // 判断列的属性
197
-  if (mergeCol.indexOf(column.property) !== -1) {
198
-    // 判断其值是不是为0
199
-    if (mergeObj.value[column.property][rowIndex]) {
200
-      return [mergeObj.value[column.property][rowIndex], 1];
201
-    } else {
202
-      // 如果为0则为需要合并的行
203
-      return [0, 0];
204
-    }
205
-  }
206
-};
207
-
208
-// getSpanArr方法
209
-const getSpanArr = (data: any) => {
210
-  const mergeCol = ["gameName", "warehouseName", "materials1", "materials2"];
211
-  mergeCol.forEach((key: any) => {
212
-    let count = 0; // 用来记录需要合并行的起始位置
213
-    mergeObj.value[key] = []; // 记录每一列的合并信息
214
-    data.forEach((item: any, index: number) => {
215
-      // index == 0表示数据为第一行,直接 push 一个 1
216
-      if (index === 0) {
217
-        mergeObj.value[key].push(1);
218
-      } else {
219
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
220
-        if (item[key] === data[index - 1][key]) {
221
-          mergeObj.value[key][count] += 1;
222
-          mergeObj.value[key].push(0);
223
-        } else {
224
-          // 如果当前行和上一行其值不相等
225
-          count = index; // 记录当前位置
226
-          mergeObj.value[key].push(1); // 重新push 一个 1
227
-        }
228
-      }
229
-    });
230
-  });
231
-  tableLoading.value = false;
232
-};
7
+import detailedTable from "@/views/dataStatistics/components/detailedTable.vue";
233 8
 </script>
9
+
10
+<style lang="scss" scoped></style>

+ 2 - 253
src/views/dataStatistics/reliefMaterial/index.vue

@@ -1,259 +1,8 @@
1 1
 <!-- 救灾物资数量价值表 -->
2 2
 <template>
3
-  <basic-container>
4
-    <el-form class="whole_form">
5
-      <el-row :gutter="20">
6
-        <el-col :span="6" v-if="userInfo.deptType === '1'">
7
-          <el-form-item label="省份">
8
-            <el-select v-model="searchList.provinceDeptIdList" clearable multiple @change="getSupplies">
9
-              <el-option v-for="item in cityList" :key="item.deptId" :label="item.name" :value="item.deptId" />
10
-            </el-select>
11
-          </el-form-item>
12
-        </el-col>
13
-        <el-col :span="6" v-if="userInfo.deptType === '1'">
14
-          <el-form-item label="储备仓库">
15
-            <el-select
16
-              v-model="searchList.deptIdList"
17
-              clearable
18
-              multiple
19
-              :disabled="searchList.provinceDeptIdList.length === 0"
20
-              :placeholder="searchList.provinceDeptIdList.length === 0 ? '请先选择省份' : '请选择储备仓库'"
21
-            >
22
-              <el-option
23
-                v-for="item in warehouseList"
24
-                :key="item.deptId"
25
-                :label="item.abbreviationName"
26
-                :value="item.deptId"
27
-              />
28
-            </el-select>
29
-          </el-form-item>
30
-        </el-col>
31
-        <el-col :span="6" v-if="userInfo.deptType === '2'">
32
-          <el-form-item label="储备仓库">
33
-            <el-select v-model="searchList.deptIdList" clearable multiple placeholder="请选择储备仓库">
34
-              <el-option
35
-                v-for="item in warehouseList"
36
-                :key="item.deptId"
37
-                :label="item.abbreviationName"
38
-                :value="item.deptId"
39
-              />
40
-            </el-select>
41
-          </el-form-item>
42
-        </el-col>
43
-        <el-col :span="6">
44
-          <el-form-item label="物资类别">
45
-            <el-select v-model="searchList.dmUpcode1List" clearable multiple>
46
-              <el-option v-for="item in suppliesList" :key="item.id" :label="item.name" :value="item.code" />
47
-            </el-select>
48
-          </el-form-item>
49
-        </el-col>
50
-        <el-col :span="6">
51
-          <el-form-item label="物资名称">
52
-            <el-input v-model="searchList.dmUpname2" clearable />
53
-          </el-form-item>
54
-        </el-col>
55
-      </el-row>
56
-      <el-row class="btn_center">
57
-        <el-button :icon="Search" type="primary" @click="getList">查询</el-button>
58
-        <el-button :icon="RefreshRight" @click="clearSearch">清空</el-button>
59
-      </el-row>
60
-    </el-form>
61
-
62
-    <el-button type="primary" :icon="Download" style="margin-bottom: 10px" @click="downloadExcel">导出</el-button>
63
-    <el-table :data="tableData" stripe border :span-method="arraySpanMethod">
64
-      <el-table-column type="index" label="序号" header-align="center" align="center" />
65
-      <el-table-column prop="upidName" label="省份" header-align="center" align="center" />
66
-      <el-table-column prop="username" label="储备仓库" header-align="center" align="center" width="120" />
67
-      <template v-for="item in headerName" :key="item">
68
-        <el-table-column :label="item.dmUpname" header-align="center" align="center">
69
-          <template v-for="iten in item.children" :key="iten">
70
-            <el-table-column :label="iten.dmUpname" header-align="center" align="center">
71
-              <el-table-column :prop="iten.dmUpcode" :label="iten.units" header-align="center" align="center" />
72
-            </el-table-column>
73
-          </template>
74
-        </el-table-column>
75
-      </template>
76
-      <el-table-column prop="tolNum" label="数量总计(件)" header-align="center" align="center" />
77
-      <el-table-column prop="tolMoney" label="总价值(万元)" header-align="center" align="center" />
78
-    </el-table>
79
-  </basic-container>
3
+  <valueTable :payload="['300']" fileName="救灾物资数量价值表" />
80 4
 </template>
81 5
 
82 6
 <script setup lang="ts">
83
-import { ref } from "vue";
84
-
85
-import { handleTree } from "@/utils/util";
86
-import { useGetters } from "@/hooks/storeHooks";
87
-import { exportExcel } from "@/components/export2xlsx";
88
-import {
89
-  getDroughtResistantHeader,
90
-  getDroughtResistantList,
91
-  getCityList,
92
-  getSysTreeDict
93
-} from "@/api/dataStatistics/index";
94
-import { Search, RefreshRight, Download } from "@element-plus/icons-vue";
95
-
96
-const headerName: any = ref([]); // 展示用表头
97
-const headerProps: any = ref([]); // 数据对应code
98
-const tableData: any = ref([]); // 列表数据
99
-const searchList: any = ref({}); // 搜索数据
100
-const mergeObj: any = ref({}); // 处理合并单元格数据
101
-const cityList: any = ref([]); // 省份信息
102
-const warehouseList: any = ref([]); // 储备仓库
103
-const suppliesList: any = ref([]); // 物资类别
104
-const exportHeaderName = ref([]); // 导出用表头
105
-
106
-const { userInfo } = useGetters(["userInfo"]);
107
-
108
-if (userInfo.value.deptType === "1") {
109
-  // 获取省份列表
110
-  getCityList({ deptType: 2 }).then((res: any) => {
111
-    if (res.code === 0) {
112
-      cityList.value = res.data;
113
-    }
114
-  });
115
-} else {
116
-  // 获取储备仓库
117
-  getCityList({ parentIdList: [userInfo.value.deptId] }).then((res: any) => {
118
-    if (res.code === 0) {
119
-      warehouseList.value = res.data;
120
-    }
121
-  });
122
-}
123
-
124
-// 根据省份列表获取储备仓库
125
-const getSupplies = (value: string[]) => {
126
-  getCityList({ parentIdList: value }).then((res: any) => {
127
-    if (res.code === 0) {
128
-      warehouseList.value = res.data;
129
-    }
130
-  });
131
-};
132
-
133
-// 获取物资类别
134
-getSysTreeDict({ type: 1, difference: 2, parentCodeList: ["300"] }).then((res: any) => {
135
-  if (res.code === 0) {
136
-    suppliesList.value = res.data;
137
-  }
138
-});
139
-
140
-// 获取表头数据
141
-getDroughtResistantHeader({ matype1: ["300"] }).then((res: any) => {
142
-  if (res.code === 0) {
143
-    res.data
144
-      .map((item: any) => {
145
-        const parent = {
146
-          dmUpcode: item.matypecode2,
147
-          dmUpname: item.matypename2
148
-        };
149
-        const own = {
150
-          dmUpcode: item.matypecode3,
151
-          dmUpname: item.matypename3,
152
-          units: item.matypename4
153
-        };
154
-        return [parent, own];
155
-      })
156
-      .forEach((item: any) => {
157
-        headerName.value.push(...item);
158
-      });
159
-    exportHeaderName.value = res.data;
160
-    headerName.value = handleTree(headerName.value, "dmUpcode");
161
-    headerProps.value = res.data.map((item: any) => item.matypecode3);
162
-    headerProps.value.unshift("upidName", "username");
163
-  }
164
-  getList();
165
-});
166
-
167
-// getSpanArr方法
168
-const getSpanArr = (data: any) => {
169
-  const mergeCol = ["upidName", "username"];
170
-  mergeCol.forEach((key: any) => {
171
-    let count = 0; // 用来记录需要合并行的起始位置
172
-    mergeObj.value[key] = []; // 记录每一列的合并信息
173
-    data.forEach((item: any, index: number) => {
174
-      // index == 0表示数据为第一行,直接 push 一个 1
175
-      if (index === 0) {
176
-        mergeObj.value[key].push(1);
177
-      } else {
178
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
179
-        if (item[key] === data[index - 1][key]) {
180
-          mergeObj.value[key][count] += 1;
181
-          mergeObj.value[key].push(0);
182
-        } else {
183
-          // 如果当前行和上一行其值不相等
184
-          count = index; // 记录当前位置
185
-          mergeObj.value[key].push(1); // 重新push 一个 1
186
-        }
187
-      }
188
-    });
189
-  });
190
-};
191
-
192
-// 获取表格数据
193
-const getList = () => {
194
-  const data = {
195
-    ...searchList.value,
196
-    dmUpcode0List: ["300"]
197
-  };
198
-  getDroughtResistantList(data).then((res: any) => {
199
-    if (res.code === 0) {
200
-      tableData.value = res.data
201
-        .map((item: any) => {
202
-          const retVal: any = ref({
203
-            ...item.map
204
-          });
205
-          retVal.value.upidName = item.upidName;
206
-          retVal.value.username = item.username;
207
-          retVal.value.tolMoney = item.tolMoney;
208
-          retVal.value.tolNum = item.tolNum;
209
-
210
-          return retVal.value;
211
-        })
212
-        .filter((item: any) => {
213
-          headerProps.value.filter((ite: any) => {
214
-            if (!item[ite]) {
215
-              item[ite] = 0;
216
-            }
217
-          });
218
-          return item;
219
-        });
220
-      getSpanArr(tableData.value);
221
-    }
222
-  });
223
-};
224
-
225
-const clearSearch = () => {
226
-  searchList.value = {
227
-    provinceDeptIdList: [],
228
-    deptIdList: [],
229
-    dmUpcode1List: [],
230
-    dmUpname2: ""
231
-  };
232
-  getList();
233
-};
234
-
235
-const arraySpanMethod = ({ column, rowIndex, columnIndex }: any) => {
236
-  if (rowIndex === 0) {
237
-    if (columnIndex === 1) {
238
-      return [1, 2];
239
-    } else if (columnIndex === 2) {
240
-      return [0, 0];
241
-    }
242
-  }
243
-  const mergeCol = ["upidName", "username"];
244
-  // 判断列的属性
245
-  if (mergeCol.indexOf(column.property) !== -1) {
246
-    // 判断其值是不是为0
247
-    if (mergeObj.value[column.property][rowIndex]) {
248
-      return [mergeObj.value[column.property][rowIndex], 1];
249
-    } else {
250
-      // 如果为0则为需要合并的行
251
-      return [0, 0];
252
-    }
253
-  }
254
-};
255
-
256
-const downloadExcel = () => {
257
-  exportExcel(tableData.value, exportHeaderName.value, headerProps.value, "救灾物资数量价值表");
258
-};
7
+import valueTable from "@/views/dataStatistics/components/valueTable.vue";
259 8
 </script>

+ 4 - 226
src/views/dataStatistics/reliefMaterialsDetailed/index.vue

@@ -1,232 +1,10 @@
1 1
 <!-- 救灾物资明细统计表 -->
2 2
 <template>
3
-  <basic-container>
4
-    <el-form class="whole_form">
5
-      <el-row :gutter="20">
6
-        <el-col :span="6" v-if="userInfo.deptType === '1'">
7
-          <el-form-item label="省份">
8
-            <el-select v-model="searchList.gameDeptId" multiple clearable @change="getSupplies">
9
-              <el-option v-for="item in cityList" :key="item.deptId" :label="item.name" :value="item.deptId" />
10
-            </el-select>
11
-          </el-form-item>
12
-        </el-col>
13
-        <el-col :span="6" v-if="userInfo.deptType === '1'">
14
-          <el-form-item label="储备仓库">
15
-            <el-select
16
-              multiple
17
-              clearable
18
-              v-model="searchList.warehouseDeptId"
19
-              :disabled="!searchList.gameDeptId"
20
-              :placeholder="!searchList.gameDeptId ? '请先选择省份' : '请选择储备仓库'"
21
-            >
22
-              <el-option
23
-                v-for="item in warehouseList"
24
-                :key="item.deptId"
25
-                :label="item.abbreviationName"
26
-                :value="item.deptId"
27
-              />
28
-            </el-select>
29
-          </el-form-item>
30
-        </el-col>
31
-        <el-col :span="6" v-if="userInfo.deptType === '2'">
32
-          <el-form-item label="储备仓库">
33
-            <el-select v-model="searchList.warehouseDeptId" multiple clearable placeholder="请选择储备仓库">
34
-              <el-option
35
-                v-for="item in warehouseList"
36
-                :key="item.deptId"
37
-                :label="item.abbreviationName"
38
-                :value="item.deptId"
39
-              />
40
-            </el-select>
41
-          </el-form-item>
42
-        </el-col>
43
-        <el-col :span="6">
44
-          <el-form-item label="物资类别">
45
-            <el-select v-model="searchList.dmUpcode1List" clearable multiple>
46
-              <el-option v-for="item in suppliesList" :key="item.id" :label="item.name" :value="item.code" />
47
-            </el-select>
48
-          </el-form-item>
49
-        </el-col>
50
-        <el-col :span="6">
51
-          <el-form-item label="物资名称">
52
-            <el-input v-model="searchList.dmUpname2" clearable />
53
-          </el-form-item>
54
-        </el-col>
55
-      </el-row>
56
-      <el-row class="btn_center">
57
-        <el-button :icon="Search" type="primary" @click="getList">查询</el-button>
58
-        <el-button :icon="RefreshRight" @click="clearSearch">清空</el-button>
59
-      </el-row>
60
-    </el-form>
61
-
62
-    <el-table :data="tableData" stripe border :span-method="arraySpanMethod" v-loading="tableLoading">
63
-      <!-- <el-table :data="tableData" stripe border> -->
64
-      <el-table-column type="index" label="序号" header-align="center" align="center" />
65
-      <el-table-column prop="gameName" label="省份" header-align="center" align="center" />
66
-      <el-table-column prop="warehouseName" label="储备仓库" header-align="center" align="center" width="120" />
67
-      <el-table-column prop="materials1" label="物资大类" header-align="center" align="center" />
68
-      <el-table-column prop="materials2" label="物资类别" header-align="center" align="center" />
69
-      <el-table-column prop="materials3" label="物资名称" header-align="center" align="center" />
70
-      <el-table-column prop="materials4" label="物资单位" header-align="center" align="center" />
71
-      <el-table-column prop="specs" label="规格" header-align="center" align="center" />
72
-      <el-table-column prop="quantity" label="数量" header-align="center" align="center" />
73
-      <el-table-column prop="inboundTime" label="入库时间" header-align="center" align="center" />
74
-      <el-table-column prop="unitPrice" label="单价(元)" header-align="center" align="center" />
75
-      <el-table-column prop="totalPrice" label="总价(万元)" header-align="center" align="center">
76
-        <template #default="{ row }">
77
-          {{ row.totalPrice ?? row.warehouseTotalPrice }}
78
-        </template>
79
-      </el-table-column>
80
-      <el-table-column prop="remarks" label="备注" header-align="center" align="center" />
81
-    </el-table>
82
-  </basic-container>
3
+  <detailedTable :payload="['300']" />
83 4
 </template>
84 5
 
85 6
 <script setup lang="ts">
86
-import { ref } from "vue";
87
-
88
-import { useGetters } from "@/hooks/storeHooks";
89
-import { Search, RefreshRight } from "@element-plus/icons-vue";
90
-import { getDetailList, getCityList, getSysTreeDict } from "@/api/dataStatistics/index";
91
-
92
-const tableData: any = ref([]);
93
-const tableLoading = ref(false);
94
-const searchList: any = ref({
95
-  gameDeptId: [],
96
-  warehouseDeptId: [],
97
-  dmUpcode1List: [],
98
-  dmUpname2: ""
99
-});
100
-const mergeObj: any = ref({});
101
-const cityList: any = ref([]);
102
-const warehouseList: any = ref([]);
103
-const suppliesList: any = ref([]);
104
-
105
-const { userInfo } = useGetters(["userInfo"]);
106
-
107
-if (userInfo.value.deptType === "1") {
108
-  // 获取省份列表
109
-  getCityList({ deptType: 2 }).then((res: any) => {
110
-    if (res.code === 0) {
111
-      cityList.value = res.data;
112
-      searchList.value.gameDeptId = [cityList.value[0].deptId];
113
-      getSupplies(searchList.value.gameDeptId);
114
-      getList();
115
-    }
116
-  });
117
-} else {
118
-  // 获取储备仓库
119
-  getCityList({ parentIdList: [userInfo.value.deptId] }).then((res: any) => {
120
-    if (res.code === 0) {
121
-      warehouseList.value = res.data;
122
-      searchList.value.warehouseDeptId = [warehouseList.value[0].deptId];
123
-    }
124
-  });
125
-}
126
-
127
-// 根据省份列表获取储备仓库
128
-const getSupplies = (value: string) => {
129
-  getCityList({ parentIdList: value }).then((res: any) => {
130
-    if (res.code === 0) {
131
-      warehouseList.value = res.data;
132
-    }
133
-  });
134
-};
135
-
136
-// 获取物资类别
137
-getSysTreeDict({ type: 1, difference: 2, parentCodeList: ["300"] }).then((res: any) => {
138
-  if (res.code === 0) {
139
-    suppliesList.value = res.data;
140
-  }
141
-});
142
-
143
-const clearSearch = () => {
144
-  searchList.value = {
145
-    gameDeptId: [],
146
-    warehouseDeptId: [],
147
-    dmUpcode1List: [],
148
-    dmUpname2: ""
149
-  };
150
-  getList();
151
-};
152
-
153
-// 获取表格数据
154
-const getList = () => {
155
-  const data = {
156
-    dmUpcode0List: ["300"],
157
-    ...searchList.value
158
-  };
159
-  tableLoading.value = true;
160
-  getDetailList(data).then((res: any) => {
161
-    if (res.code === 0) {
162
-      tableData.value = res.data.filter((item: any) => {
163
-        if (item.gameName === null && item.totalPrice === null) {
164
-          item.unitPrice = "总价值";
165
-          return item;
166
-        } else if (item.totalPrice === null) {
167
-          item.unitPrice = "合计";
168
-          return item;
169
-        } else {
170
-          return item;
171
-        }
172
-      });
173
-      getSpanArr(tableData.value);
174
-    }
175
-  });
176
-};
177
-
178
-const arraySpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
179
-  const firstHidden = [2, 3, 4, 5, 6, 7, 8, 9];
180
-  const secondHidden = [4, 5, 6, 7, 8, 9];
181
-  if (rowIndex === 0) {
182
-    if (columnIndex === 1) {
183
-      return [1, 9];
184
-    } else if (firstHidden.includes(columnIndex)) {
185
-      return [0, 0];
186
-    }
187
-  } else if (row.unitPrice === "合计") {
188
-    if (columnIndex === 3) {
189
-      return [1, 7];
190
-    } else if (secondHidden.includes(columnIndex)) {
191
-      return [0, 0];
192
-    }
193
-  }
194
-  const mergeCol = ["gameName", "warehouseName", "materials1", "materials2"];
195
-  // 判断列的属性
196
-  if (mergeCol.indexOf(column.property) !== -1) {
197
-    // 判断其值是不是为0
198
-    if (mergeObj.value[column.property][rowIndex]) {
199
-      return [mergeObj.value[column.property][rowIndex], 1];
200
-    } else {
201
-      // 如果为0则为需要合并的行
202
-      return [0, 0];
203
-    }
204
-  }
205
-};
206
-
207
-// getSpanArr方法
208
-const getSpanArr = (data: any) => {
209
-  const mergeCol = ["gameName", "warehouseName", "materials1", "materials2"];
210
-  mergeCol.forEach((key: any) => {
211
-    let count = 0; // 用来记录需要合并行的起始位置
212
-    mergeObj.value[key] = []; // 记录每一列的合并信息
213
-    data.forEach((item: any, index: number) => {
214
-      // index == 0表示数据为第一行,直接 push 一个 1
215
-      if (index === 0) {
216
-        mergeObj.value[key].push(1);
217
-      } else {
218
-        // 判断当前行是否与上一行其值相等 如果相等 在 count 记录的位置其值 +1 表示当前行需要合并 并push 一个 0 作为占位
219
-        if (item[key] === data[index - 1][key]) {
220
-          mergeObj.value[key][count] += 1;
221
-          mergeObj.value[key].push(0);
222
-        } else {
223
-          // 如果当前行和上一行其值不相等
224
-          count = index; // 记录当前位置
225
-          mergeObj.value[key].push(1); // 重新push 一个 1
226
-        }
227
-      }
228
-    });
229
-  });
230
-  tableLoading.value = false;
231
-};
7
+import detailedTable from "@/views/dataStatistics/components/detailedTable.vue";
232 8
 </script>
9
+
10
+<style lang="scss" scoped></style>