sunxuewei преди 1 година
родител
ревизия
1cb34838cd

+ 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 = ""

+ 9 - 0
src/api/dataStatistics/index.ts

@@ -48,3 +48,12 @@ export function getCityList(data: any) {
48 48
     data
49 49
   });
50 50
 }
51
+
52
+// 数据统计 —— 获取详情列表数据
53
+export function getDetailList(data: any) {
54
+  return request({
55
+    url: "/admin/in/selectListByDept",
56
+    method: "post",
57
+    data
58
+  });
59
+}

+ 7 - 7
src/components/export2xlsx/index.ts

@@ -3,7 +3,7 @@ import { writeFile, utils } from "xlsx";
3 3
 
4 4
 export const exportExcel = (fileData: any[], headerName: any[], headerProp: string[], fileName: string) => {
5 5
   // console.log(fileData, headerName, headerProp, fileName);
6
-  const merges: any = {};
6
+  const repeatingData: any = {};
7 7
   const name: string[][] = [[], [], []];
8 8
   const data = fileData.map((obj) => {
9 9
     return headerProp.map((prop) => obj[prop]);
@@ -14,14 +14,14 @@ export const exportExcel = (fileData: any[], headerName: any[], headerProp: stri
14 14
   name[0].forEach((item, index) => {
15 15
     const itemIndex = name[0].findIndex((ite) => ite === item);
16 16
     if (itemIndex !== index) {
17
-      merges[item] = { s: { r: 0, c: itemIndex }, e: { r: 0, c: index } };
17
+      repeatingData[item] = { s: { r: 0, c: itemIndex }, e: { r: 0, c: index } };
18 18
     }
19 19
   });
20 20
   const cols = data.map((item) => item[0]);
21 21
   cols.forEach((item, index) => {
22 22
     const itemIndex = cols.findIndex((ite) => ite === item);
23 23
     if (itemIndex !== index) {
24
-      merges[item] = { s: { r: itemIndex + 3, c: 0 }, e: { r: index + 3, c: 0 } };
24
+      repeatingData[item] = { s: { r: itemIndex + 3, c: 0 }, e: { r: index + 3, c: 0 } };
25 25
     }
26 26
   });
27 27
   data.unshift(...name);
@@ -35,15 +35,15 @@ export const exportExcel = (fileData: any[], headerName: any[], headerProp: stri
35 35
     horizontal: "center",
36 36
     vertical: "center"
37 37
   };
38
-  const test: Range[] = [];
39
-  Object.keys(merges).forEach((item) => {
40
-    test.push(merges[item]);
38
+  const merges: Range[] = [];
39
+  Object.keys(repeatingData).forEach((item) => {
40
+    merges.push(repeatingData[item]);
41 41
   });
42 42
   ws["!merges"] = [
43 43
     { s: { r: 0, c: 0 }, e: { r: 2, c: 0 } },
44 44
     { s: { r: 0, c: 1 }, e: { r: 2, c: 1 } },
45 45
     { s: { r: 3, c: 0 }, e: { r: 3, c: 1 } },
46
-    ...test
46
+    ...merges
47 47
   ];
48 48
   utils.book_append_sheet(wb, ws, fileName);
49 49
   writeFile(wb, `${fileName}.xlsx`);

+ 233 - 0
src/views/dataStatistics/floodDroughtPrecaution/index.vue

@@ -0,0 +1,233 @@
1
+<!-- 防汛抗旱明细统计表 -->
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>
83
+</template>
84
+
85
+<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
+};
233
+</script>

+ 232 - 0
src/views/dataStatistics/reliefMaterialsDetailed/index.vue

@@ -0,0 +1,232 @@
1
+<!-- 救灾物资明细统计表 -->
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>
83
+</template>
84
+
85
+<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
+};
232
+</script>