feat: 月度数据-数据总览前后端

This commit is contained in:
LokerL 2024-09-12 16:50:29 +08:00
parent 6202f3765a
commit f10cb687fa
11 changed files with 347 additions and 51 deletions

View File

@ -1,11 +1,7 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.text.StrFormatter; import com.ruoyi.common.core.text.StrFormatter;
@ -681,4 +677,27 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
} }
return sb.toString(); return sb.toString();
} }
public static String toLowerCaseCamelCase(String input) {
StringBuilder output = new StringBuilder();
String[] words = input.split("_");
output.append(words[0]);
for (int i = 1; i < words.length; i++) {
output.append(Character.toUpperCase(words[i].charAt(0)));
output.append(words[i].substring(1).toLowerCase());
}
return output.toString();
}
public static final List<Map<String, Object>> camelCaseMapListKey(List<Map<String, Object>> list) {
List<Map<String, Object>> result = new ArrayList<>();
for (Map<String, Object> map : list) {
Map<String, Object> lowerCaseMap = new HashMap<>();
for (String key : map.keySet()) {
lowerCaseMap.put(toLowerCaseCamelCase(key.toLowerCase()), map.get(key));
}
result.add(lowerCaseMap);
}
return result;
}
} }

View File

@ -12,6 +12,7 @@ import com.ruoyi.project.oil.domain.monitor.ThDevice;
import com.ruoyi.project.oil.domain.monitor.ThDeviceReport; import com.ruoyi.project.oil.domain.monitor.ThDeviceReport;
import com.ruoyi.project.oil.service.IOilThDeviceService; import com.ruoyi.project.oil.service.IOilThDeviceService;
import com.ruoyi.project.oil.service.ThDeviceReportMonthService; import com.ruoyi.project.oil.service.ThDeviceReportMonthService;
import com.ruoyi.project.oil.service.impl.OilThDeviceReportService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -32,6 +33,9 @@ public class OilStatisticsController extends BaseController {
@Autowired @Autowired
private ThDeviceReportMonthService thDeviceReportMonthService; private ThDeviceReportMonthService thDeviceReportMonthService;
@Autowired
private OilThDeviceReportService oilThDeviceReportService;
@GetMapping(value = "/getDeviceList/{id}") @GetMapping(value = "/getDeviceList/{id}")
public TableDataInfo getDeviceList(@PathVariable("id") Long id) { public TableDataInfo getDeviceList(@PathVariable("id") Long id) {
startPage(); startPage();
@ -77,7 +81,7 @@ public class OilStatisticsController extends BaseController {
public AjaxResult reportCenter(Long deptId, String month) { public AjaxResult reportCenter(Long deptId, String month) {
List<Map<String, Object>> resultCurrMonth = oilThDeviceService.selectAllAvgByMonth(deptId, month); List<Map<String, Object>> resultCurrMonth = oilThDeviceService.selectAllAvgByMonth(deptId, month);
// 根据month获取上个月 字符串 month: 2024-09 -> lastMonth: 2024-081月份的上个月是12月份 // 根据month获取上个月 字符串 month: 2024-09 -> lastMonth: 2024-081月份的上个月是12月份
List<Map<String, Object>> resultLastMonth = oilThDeviceService.selectAllAvgByMonth(deptId, getLastMonth(month)); List<Map<String, Object>> resultLastMonth = oilThDeviceService.selectAllAvgByMonth(deptId, getPreviousMonth(month));
// 月度报表中的数据 // 月度报表中的数据
List<Map<String, Object>> result = oilThDeviceService.selectDeptAvgByMonth(deptId, month); List<Map<String, Object>> result = oilThDeviceService.selectDeptAvgByMonth(deptId, month);
// 将所有的数据放入一个map中 // 将所有的数据放入一个map中
@ -88,7 +92,7 @@ public class OilStatisticsController extends BaseController {
return success(resultMap); return success(resultMap);
} }
public static String getLastMonth(String month) { public static String getPreviousMonth(String month) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
if (month.length() == 6) { if (month.length() == 6) {
month = month.substring(0, 5) + "0" + month.substring(5); month = month.substring(0, 5) + "0" + month.substring(5);
@ -98,7 +102,7 @@ public class OilStatisticsController extends BaseController {
return lastMonthDate.format(formatter); return lastMonthDate.format(formatter);
} }
@GetMapping("/getDeviceReportMonthList") @GetMapping("/monthData/getDeviceReportMonthList")
public TableDataInfo getDeviceReportMonthList(Long deptId, String year, String month, int pageNum, int pageSize) { public TableDataInfo getDeviceReportMonthList(Long deptId, String year, String month, int pageNum, int pageSize) {
Page<Object> page = PageHelper.startPage(pageNum, pageSize); Page<Object> page = PageHelper.startPage(pageNum, pageSize);
List<Map<String, Object>> result = thDeviceReportMonthService.selectThDeviceReportMonthList(deptId, year, month); List<Map<String, Object>> result = thDeviceReportMonthService.selectThDeviceReportMonthList(deptId, year, month);
@ -110,8 +114,20 @@ public class OilStatisticsController extends BaseController {
return rspData; return rspData;
} }
@PostMapping("/updateDeviceReportMonth") @PostMapping("/monthData/updateDeviceReportMonth")
public AjaxResult updateDeviceReportMonth(@RequestBody ThDeviceReportMonth thDeviceReportMonth) { public AjaxResult updateDeviceReportMonth(@RequestBody ThDeviceReportMonth thDeviceReportMonth) {
return toAjax(thDeviceReportMonthService.updateThDeviceReportMonth(thDeviceReportMonth)); return toAjax(thDeviceReportMonthService.updateThDeviceReportMonth(thDeviceReportMonth));
} }
@GetMapping("/monthData/dataOverview")
public AjaxResult dataOverview(Long deptId, String month) {
List<Map<String, Object>> monthReportDataOverview = oilThDeviceReportService.monthReportDataOverview(deptId, month);
List<Map<String, Object>> preMonthReportDataOverview = oilThDeviceReportService.monthReportDataOverview(deptId, getPreviousMonth(month));
List<Map<String, Object>> monthReportDataOverviewDeviceDs = oilThDeviceReportService.monthReportDataOverviewDeviceDs(deptId, month);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("monthReportDataOverview", monthReportDataOverview);
resultMap.put("preMonthReportDataOverview", preMonthReportDataOverview);
resultMap.put("monthReportDataOverviewDeviceDs", monthReportDataOverviewDeviceDs);
return success(resultMap);
}
} }

View File

@ -52,4 +52,16 @@ public interface ThDeviceReportMapper {
*/ */
@MapKey("month") @MapKey("month")
List<Map<String, Object>> selectAllAvgByMonth(@Param("deptId") Long deptId, @Param("month") String month); List<Map<String, Object>> selectAllAvgByMonth(@Param("deptId") Long deptId, @Param("month") String month);
/**
* 按月度统计ds, gbz ,dbz的平均值
*/
@MapKey("month")
List<Map<String, Object>> monthReportDataOverview(@Param("deptId") Long deptId, @Param("month") String month);
/**
* 按月度统计ds, gbz ,dbz的平均值
*/
@MapKey("month")
List<Map<String, Object>> monthReportDataOverviewDeviceDs(@Param("deptId") Long deptId, @Param("month") String month);
} }

View File

@ -0,0 +1,10 @@
package com.ruoyi.project.oil.service;
import java.util.List;
import java.util.Map;
public interface IOilThDeviceReportService {
List<Map<String, Object>> monthReportDataOverview(Long deptId, String month);
List<Map<String, Object>> monthReportDataOverviewDeviceDs(Long deptId, String month);
}

View File

@ -0,0 +1,29 @@
package com.ruoyi.project.oil.service.impl;
import com.ruoyi.project.oil.mapper.ThDeviceReportMapper;
import com.ruoyi.project.oil.service.IOilThDeviceReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import static com.ruoyi.common.utils.StringUtils.camelCaseMapListKey;
@Service
public class OilThDeviceReportService implements IOilThDeviceReportService {
@Autowired
private ThDeviceReportMapper thDeviceReportMapper;
@Override
public List<Map<String, Object>> monthReportDataOverview(Long deptId, String month) {
return camelCaseMapListKey(thDeviceReportMapper.monthReportDataOverview(deptId, month));
}
@Override
public List<Map<String, Object>> monthReportDataOverviewDeviceDs(Long deptId, String month) {
return camelCaseMapListKey(thDeviceReportMapper.monthReportDataOverviewDeviceDs(deptId, month));
}
}

View File

@ -11,6 +11,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static com.ruoyi.common.utils.StringUtils.camelCaseMapListKey;
/** /**
* @author Lenovo * @author Lenovo
* @description 针对表TH_DEVICE_REPORT_MONTH1(设备月表)的数据库操作Service实现 * @description 针对表TH_DEVICE_REPORT_MONTH1(设备月表)的数据库操作Service实现
@ -24,35 +26,13 @@ public class ThDeviceReportMonthServiceImpl implements ThDeviceReportMonthServic
@Override @Override
public List<Map<String, Object>> selectThDeviceReportMonthList(Long deptId, String year, String month) { public List<Map<String, Object>> selectThDeviceReportMonthList(Long deptId, String year, String month) {
// return thDeviceReportMonthMapper.selectThDeviceReportMonthList(deptId, year, month); return camelCaseMapListKey(thDeviceReportMonthMapper.selectThDeviceReportMonthList(deptId, year, month));
List<Map<String, Object>> result = new ArrayList<>();
List<Map<String, Object>> list = thDeviceReportMonthMapper.selectThDeviceReportMonthList(deptId, year, month);
for (Map<String, Object> map : list) {
Map<String, Object> lowerCaseMap = new HashMap<>();
for (String key : map.keySet()) {
lowerCaseMap.put(toLowerCaseCamelCase(key.toLowerCase()), map.get(key));
}
result.add(lowerCaseMap);
}
return result;
} }
@Override @Override
public int updateThDeviceReportMonth(ThDeviceReportMonth thDeviceReportMonth) { public int updateThDeviceReportMonth(ThDeviceReportMonth thDeviceReportMonth) {
return thDeviceReportMonthMapper.updateThDeviceReportMonth(thDeviceReportMonth); return thDeviceReportMonthMapper.updateThDeviceReportMonth(thDeviceReportMonth);
} }
public static String toLowerCaseCamelCase(String input) {
StringBuilder output = new StringBuilder();
String[] words = input.split("_");
output.append(words[0]);
for (int i = 1; i < words.length; i++) {
output.append(Character.toUpperCase(words[i].charAt(0)));
output.append(words[i].substring(1).toLowerCase());
}
return output.toString();
}
} }

View File

@ -122,4 +122,41 @@
AND TO_CHAR(d.report_time, 'YYYY-MM') = #{month} AND TO_CHAR(d.report_time, 'YYYY-MM') = #{month}
GROUP BY TO_CHAR(d.report_time, 'YYYY-MM') GROUP BY TO_CHAR(d.report_time, 'YYYY-MM')
</select> </select>
<select id="monthReportDataOverview" parameterType="map" resultType="map">
SELECT TO_CHAR(d.report_time, 'YYYY-MM') AS month,
ROUND(AVG(TO_NUMBER(d.ds)), 8) AS avg_ds,
ROUND(AVG(TO_NUMBER(d.dbz)), 8) AS avg_dbz,
ROUND(AVG(TO_NUMBER(d.gbz)), 8) AS avg_gbz
FROM th_device_report d
WHERE d.sn IN (SELECT d.sn
FROM th_device d
LEFT JOIN sys_dept p ON d.dept_id = p.dept_id
WHERE d.dept_id IN (SELECT dept_id
FROM sys_dept START WITH dept_id = #{deptId}
CONNECT BY PRIOR dept_id = parent_id))
AND TO_CHAR(d.report_time, 'YYYY-MM') = #{month}
GROUP BY TO_CHAR(d.report_time, 'YYYY-MM')
</select>
<select id="monthReportDataOverviewDeviceDs" parameterType="map" resultType="map">
SELECT d.sn,
p.dept_name,
pp.dept_name as "gang_qu",
ROUND(AVG(TO_NUMBER(d.ds)), 8) AS avg_ds
FROM th_device_report d
LEFT JOIN th_device td ON d.sn = td.sn
LEFT JOIN sys_dept p ON td.dept_id = p.dept_id
LEFT JOIN sys_dept pp ON p.parent_id = pp.dept_id
WHERE d.sn IN (SELECT d.sn
FROM th_device d
LEFT JOIN sys_dept p ON d.dept_id = p.dept_id
WHERE d.dept_id IN (SELECT dept_id
FROM sys_dept START WITH dept_id = #{deptId}
CONNECT BY PRIOR dept_id = parent_id))
AND TO_CHAR(d.report_time, 'YYYY-MM') = #{month}
GROUP BY d.sn, p.dept_name, pp.dept_name
ORDER BY pp.dept_name, p.dept_name
</select>
</mapper> </mapper>

View File

@ -2,7 +2,7 @@ import request from '@/utils/request'
export function getDeviceReportMonthList(params) { export function getDeviceReportMonthList(params) {
return request({ return request({
url: '/statistics/getDeviceReportMonthList', url: '/statistics/monthData/getDeviceReportMonthList',
params: params, params: params,
method: 'get', method: 'get',
}) })
@ -10,8 +10,16 @@ export function getDeviceReportMonthList(params) {
export function updateDeviceReportMonth(params) { export function updateDeviceReportMonth(params) {
return request({ return request({
url: '/statistics/updateDeviceReportMonth', url: '/statistics/monthData/updateDeviceReportMonth',
data: params, data: params,
method: 'post', method: 'post',
}) })
} }
export function dataOverview(params) {
return request({
url: '/statistics/monthData/dataOverview',
params: params,
method: 'get',
})
}

View File

@ -38,6 +38,7 @@ import VueMeta from 'vue-meta'
// 字典数据组件 // 字典数据组件
import DictData from '@/components/DictData' import DictData from '@/components/DictData'
import BaiduMap from 'vue-baidu-map' import BaiduMap from 'vue-baidu-map'
import DeptTree from '@/components/DeptTree';
// 全局方法挂载 // 全局方法挂载
Vue.prototype.getDicts = getDicts Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey Vue.prototype.getConfigKey = getConfigKey
@ -50,6 +51,7 @@ Vue.prototype.download = download
Vue.prototype.handleTree = handleTree Vue.prototype.handleTree = handleTree
// 全局组件挂载 // 全局组件挂载
Vue.component('DeptTree', DeptTree)
Vue.component('DictTag', DictTag) Vue.component('DictTag', DictTag)
Vue.component('Pagination', Pagination) Vue.component('Pagination', Pagination)
Vue.component('RightToolbar', RightToolbar) Vue.component('RightToolbar', RightToolbar)

View File

@ -27,7 +27,7 @@
> >
<el-table-column prop="gangqu" label="归属港区" /> <el-table-column prop="gangqu" label="归属港区" />
<el-table-column prop="deptName" label="归属企业" /> <el-table-column prop="deptName" label="归属企业" />
<el-table-column prop="deptId" label="部门编码" /> <el-table-column prop="sn" label="设备编码" />
<el-table-column prop="year" label="年份" /> <el-table-column prop="year" label="年份" />
<el-table-column prop="month" label="月份" /> <el-table-column prop="month" label="月份" />
<el-table-column prop="avgValue" label="平均值"> <el-table-column prop="avgValue" label="平均值">
@ -67,7 +67,6 @@
</template> </template>
<script> <script>
import DeptTree from "@/components/DeptTree/index.vue";
import { import {
getDeviceReportMonthList, getDeviceReportMonthList,
updateDeviceReportMonth, updateDeviceReportMonth,
@ -75,9 +74,6 @@ import {
export default { export default {
name: "CreateReport", name: "CreateReport",
components: {
DeptTree,
},
data() { data() {
return { return {
deptId: "", deptId: "",
@ -183,8 +179,6 @@ export default {
message: "取消修改", message: "取消修改",
}); });
}); });
// this.tableData[index].enable_edit = !this.tableData[index].enable_edit;
// this.tableData = [...this.tableData];
}, },
queryData() { queryData() {
this.loading = true; this.loading = true;

View File

@ -1,23 +1,212 @@
<template> <template>
<div> <div>
<h2>DataOverview</h2> <el-row :gutter="10">
<el-col :span="6" style="margin-top: 10px; margin-bottom: 10px">
<dept-tree @deptChange="handleDeptChange" :showQuickGroup="true" />
</el-col>
<el-col :span="6" style="margin-top: 10px; margin-bottom: 10px">
<el-date-picker
v-model="dateValue"
type="month"
format="yyyy-MM"
value-format="yyyy-MM"
placeholder="选择月份"
@change="handleDateChange"
>
</el-date-picker>
</el-col>
<el-col :span="12">
<div class="export_btn"><el-button type="primary" icon="eel-icon-download" @click="exportToExcel">导出</el-button></div>
</el-col>
</el-row>
<el-row :gutter="10">
<div class="table-title">
<span>{{ dateValue.replace("-", "年") }}</span>
</div>
<el-table
:data="overViewTableData"
style="width: 100%"
:border="true"
:header-cell-style="headerStyle"
>
<el-table-column prop="month" label="名称">
<template slot-scope="scope">
{{ getTableFirstColumnName(scope.row) }}
</template>
</el-table-column>
<el-table-column
prop="avgDs"
label="读数"
align="center"
:formatter="dataFormatter"
></el-table-column>
<el-table-column
prop="avgDbz"
label="低报值"
align="center"
:formatter="dataFormatter"
></el-table-column>
<el-table-column
prop="avgGbz"
label="高报值"
align="center"
:formatter="dataFormatter"
></el-table-column>
</el-table>
<el-table
:data="cmDeviceDs"
style="width: 100%"
:border="true"
:header-cell-style="headerStyle"
>
<el-table-column prop="gangQu" label="港区"></el-table-column>
<el-table-column prop="deptName" label="企业名"></el-table-column>
<el-table-column prop="sn" label="设备编号"></el-table-column>
<el-table-column
prop="avgDs"
label="读数"
align="center"
:formatter="dataFormatter"
></el-table-column>
</el-table>
</el-row>
</div> </div>
</template> </template>
<script> <script>
import * as XLSX from "xlsx";
import { dataOverview } from "@/api/statistics/monthData.js";
export default { export default {
name: 'DataOverview', name: "DataOverview",
data() { data() {
return { return {
deptId: "",
deptName: "",
dateValue: "",
overViewTableData: [],
cmDeviceDs: [],
headerStyle: {
fontSize: '14px',
backgroundColor: '#f8f8f8',
color: '#333',
} }
};
}, },
created() { created() {
this.initDate();
}, },
methods: {
dataFormatter(row, column, cellValue, index) {
if (row.month === "") {
return cellValue;
} }
return cellValue.toFixed(2);
},
initDate() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const monthStr = month < 10 ? `0${month}` : month;
this.dateValue = `${year}-${monthStr}`;
},
handleDeptChange(value) {
this.deptId = value.deptId;
this.deptName = value.deptName;
this.queryData();
},
handleDateChange(value) {
this.queryData();
},
getTableFirstColumnName(row) {
if (row.month && row.month === this.month) {
return "本月均值";
}
if (row.month && row.month !== this.month) {
return "上月均值";
}
return "变化率";
},
queryData() {
dataOverview({
deptId: this.deptId,
month: this.dateValue,
}).then((res) => {
if (res.code === 200) {
const {
monthReportDataOverview: cmO,
preMonthReportDataOverview: pmO,
monthReportDataOverviewDeviceDs: cmDeviceDs,
} = res.data;
const currMonth = cmO[0];
const lastMonth = pmO[0];
const changeRate = {
month: "",
avgDs:
(
((currMonth.avgDs - lastMonth.avgDs) / lastMonth.avgDs) *
100
).toFixed(2) + "%",
avgDbz:
(
((currMonth.avgDbz - lastMonth.avgDbz) / lastMonth.avgDbz) *
100
).toFixed(2) + "%",
avgGbz:
(
((currMonth.avgGbz - lastMonth.avgGbz) / lastMonth.avgGbz) *
100
).toFixed(2) + "%",
};
this.overViewTableData = [currMonth, lastMonth, changeRate];
this.cmDeviceDs = cmDeviceDs;
}
});
},
exportToExcel() {
// 簿
const wb = XLSX.utils.book_new();
const filename = `${this.deptName} ${this.dateValue.replace("-", "年") + "月"}`;
//
const ws_name = "SheetJS";
const ws_data = [
[filename],
["名称", "读数", "低报值", "高报值"],
...this.overViewTableData.map(row => [this.getTableFirstColumnName(row), row.avgDs, row.avgDbz, row.avgGbz]),
["港区", "企业", "编号", "平均值"],
...this.cmDeviceDs.map(row => [row.gangQu, row.deptName, row.sn, row.avgDs]),
];
const ws = XLSX.utils.aoa_to_sheet(ws_data);
//
if(!ws['!merges']) ws['!merges'] = [];
ws['!merges'].push({s: {r: 0, c: 0}, e: {r: 0, c: 3}});
// 簿
XLSX.utils.book_append_sheet(wb, ws, ws_name);
XLSX.writeFile(wb, `${filename}.xlsx`);
},
},
};
</script> </script>
<style scoped> <style scoped>
.table-title {
border: 1px solid #EBEEF5;
display: flex;
justify-content: center;
align-items: center;
height: 45px;
span {
font-size: 18px;
color: #333;
}
}
.export_btn {
padding: 10px;
display: flex;
justify-content: flex-end;
}
</style> </style>