项目分类统计导出

This commit is contained in:
cwchen 2025-04-03 16:25:28 +08:00
parent 9a8248c032
commit 06eeaf07b6
9 changed files with 230 additions and 49 deletions

View File

@ -1,7 +1,11 @@
package com.bonus.imgTool.backstage.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.bonus.imgTool.annotation.DecryptAndVerify;
import com.bonus.imgTool.annotation.LogAnnotation;
import com.bonus.imgTool.backstage.entity.ProClassifyStatisticsVo;
import com.bonus.imgTool.backstage.entity.QueryParamDto;
import com.bonus.imgTool.backstage.entity.SynthesisQueryVo;
import com.bonus.imgTool.backstage.service.SynthesisQueryService;
@ -13,12 +17,18 @@ import com.bonus.imgTool.utils.ServerResponse;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -32,6 +42,7 @@ import java.util.Map;
*/
@RestController
@RequestMapping("/backstage/synthesisQuery/")
@Slf4j
public class SynthesisQueryController {
@Resource(name = "SynthesisQueryService")
@ -65,19 +76,19 @@ public class SynthesisQueryController {
return synthesisQueryService.generateWatermark(data.getData());
}
/*@PostMapping(value = "getProClassifyStatisticsList")
@PostMapping(value = "getProClassifyStatisticsList")
@DecryptAndVerify(decryptedClass = QueryParamDto.class)//加解密统一管理
@LogAnnotation(operModul = "综合查询-照片综合查询", operation = "查询照片", operDesc = "系统级事件",operType="查询")
@LogAnnotation(operModul = "综合查询-项目分类统计", operation = "查询列表", operDesc = "系统级事件",operType="查询")
public ServerResponse getProClassifyStatisticsList(EncryptedReq<QueryParamDto> dto) {
PageHelper.startPage(dto.getData().getPageNum(), dto.getData().getPageSize());
Map<String, Object> map = new HashMap<String, Object>();
try {
PageInfo<SysWhiteVo> pageInfo = synthesisQueryService.getProClassifyStatisticsList(dto.getData());
return ServerResponse.createSuccessPage(pageInfo, dto.getData().getPage(), dto.getData().getLimit());
} catch (Exception e) {
log.error(e.toString(), e);
}
return ServerResponse.createErrorPage(dto.getData().getPage(), dto.getData().getLimit());
}*/
return synthesisQueryService.getProClassifyStatisticsList(dto.getData());
}
@PostMapping("downloadExcel")
@DecryptAndVerify(decryptedClass = QueryParamDto.class)//加解密统一管理
@LogAnnotation(operModul = "综合查询-项目分类统计", operation = "导出列表", operDesc = "系统级事件",operType="导出")
public void downloadExcel(HttpServletResponse response, EncryptedReq<QueryParamDto> dto) {
synthesisQueryService.downloadExcel(dto.getData(),response);
}
}

View File

@ -4,6 +4,7 @@ import com.bonus.imgTool.backstage.entity.ComprehensiveQueryVo;
import com.bonus.imgTool.backstage.entity.QueryParamDto;
import com.bonus.imgTool.backstage.entity.SynthesisNumVo;
import com.bonus.imgTool.backstage.entity.SynthesisQueryVo;
import com.bonus.imgTool.backstage.entity.ProClassifyStatisticsVo;
import org.springframework.stereotype.Repository;
import java.util.List;
@ -67,5 +68,14 @@ public interface SynthesisQueryDao {
*/
String getSyData(SynthesisQueryVo vo);
/**
* 项目分类统计
* @param dto
* @return List<ProClassifyStatisticsVo>
* @author cwchen
* @date 2025/4/3 15:37
*/
List<ProClassifyStatisticsVo> getProClassifyStatisticsList(QueryParamDto dto);
void deleteComprehensiveQuery(Long id);
}

View File

@ -0,0 +1,32 @@
package com.bonus.imgTool.backstage.entity;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @className:ProClassifyStatisticsVo
* @author:cwchen
* @date:2025-04-03-15:31
* @version:1.0
* @description:项目分类统计-vo
*/
@Data
public class ProClassifyStatisticsVo extends SynthesisNumVo{
@Excel(name = "序号", width = 10.0, orderNum = "0")
private Long id;
/**工程ID*/
private Long proId;
/**工程名称*/
@Excel(name = "工程名称", width = 30.0, orderNum = "1")
private String proName;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "最后更新时间", width = 20.0, orderNum = "8",format = "yyyy-MM-dd HH:mm:ss")
private Date lastUpdateTime;
}

View File

@ -1,5 +1,7 @@
package com.bonus.imgTool.backstage.entity;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
/**
@ -13,15 +15,22 @@ import lombok.Data;
public class SynthesisNumVo {
/**总照片数量*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "总照片数量", width = 20.0, orderNum = "2")
private int totalNum;
/**安全违章*/
@Excel(name = "安全违章", width = 20.0, orderNum = "3")
private int safetyVioNum;
/**质量检查*/
@Excel(name = "质量检查", width = 20.0, orderNum = "4")
private int qualityInsNum;
/**安全措施落实*/
@Excel(name = "安全措施落实", width = 20.0, orderNum = "5")
private int safetyMeasNum;
/**协调照片*/
@Excel(name = "协调照片", width = 20.0, orderNum = "6")
private int coordinatedPhotoNum;
/**重要事项及宣传类*/
@Excel(name = "重要事项及宣传类", width = 20.0, orderNum = "7")
private int importIssuesAndPublicityNum;
}

View File

@ -5,6 +5,8 @@ import com.bonus.imgTool.backstage.entity.QueryParamDto;
import com.bonus.imgTool.backstage.entity.SynthesisQueryVo;
import com.bonus.imgTool.utils.ServerResponse;
import javax.servlet.http.HttpServletResponse;
/**
* @className:SynthesisQueryService
* @author:cwchen
@ -64,6 +66,17 @@ public interface SynthesisQueryService {
*/
ServerResponse generateWatermark(SynthesisQueryVo data);
/**
* 项目分类统计查询
* @param data
* @return ServerResponse
* @author cwchen
* @date 2025/4/3 15:31
*/
ServerResponse getProClassifyStatisticsList(QueryParamDto data);
void downloadExcel(QueryParamDto data, HttpServletResponse response);
/**
* 综合查询删除
* @param id

View File

@ -1,10 +1,10 @@
package com.bonus.imgTool.backstage.service.impl;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.bonus.imgTool.backstage.dao.SynthesisQueryDao;
import com.bonus.imgTool.backstage.entity.ComprehensiveQueryVo;
import com.bonus.imgTool.backstage.entity.QueryParamDto;
import com.bonus.imgTool.backstage.entity.SynthesisNumVo;
import com.bonus.imgTool.backstage.entity.SynthesisQueryVo;
import com.bonus.imgTool.backstage.entity.*;
import com.bonus.imgTool.backstage.service.SynthesisQueryService;
import com.bonus.imgTool.system.vo.LoginUser;
import com.bonus.imgTool.utils.HighQualityWatermark;
@ -15,14 +15,17 @@ import com.bonus.imgTool.webResult.Constants;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.security.SecurityUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@ -152,4 +155,45 @@ public class SynthesisQueryServiceImpl implements SynthesisQueryService {
String localPath = SystemUtils.getUploadPath() +File.separator+ vo.getOriginalFilePath();
return HighQualityWatermark.generateWatermark(watermarkLines,localPath);
}
@Override
public ServerResponse getProClassifyStatisticsList(QueryParamDto dto) {
List<ProClassifyStatisticsVo> list = null;
try {
String roleLevel = Optional.ofNullable(UserUtil.getLoginUser()).map(LoginUser::getRoleLevel).orElse("0");
String proIds = Optional.ofNullable(UserUtil.getLoginUser()).map(LoginUser::getProIds).orElse("-1");
if(Objects.equals(roleLevel, Constants.ROLE_LEVEL)){ // 项目部级
List<Long> proList = Arrays.stream(proIds.split(",")).map(String::trim).filter(s -> !s.isEmpty()).map(Long::valueOf).collect(Collectors.toList());
dto.setProIds(proList);
}
dto.setRoleLevel(roleLevel);
list = Optional.ofNullable(synthesisQueryDao.getProClassifyStatisticsList(dto)).orElseGet(ArrayList::new);
} catch (Exception e) {
log.error(e.toString(),e);
}
PageInfo<ProClassifyStatisticsVo> pageInfo = new PageInfo<>(list);
return ServerResponse.createSuccessPage(pageInfo, dto.getPageNum(), dto.getPageSize());
}
@Override
public void downloadExcel(QueryParamDto dto, HttpServletResponse response) {
try {
List<ProClassifyStatisticsVo> list = list = Optional.ofNullable(synthesisQueryDao.getProClassifyStatisticsList(dto)).orElseGet(ArrayList::new);
final Long[] num = {1L};
list.forEach(vo -> {
vo.setId(num[0]);
num[0]++;
});
ExportParams exportParams = new ExportParams("项目分类统计", "项目分类统计", ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, ProClassifyStatisticsVo.class, list);
response.setContentType("application/vnd.ms-excel");
response.setHeader("content-disposition", "attachment;fileName=" + URLEncoder.encode("项目分类统计" + ".xlsx", "UTF-8"));
ServletOutputStream outputStream = response.getOutputStream();
workbook.write(outputStream);
outputStream.close();
workbook.close();
} catch (Exception e) {
log.error(e.toString(), e);
}
}
}

View File

@ -214,6 +214,35 @@
<select id="getSyData" resultType="java.lang.String">
SELECT watermark_file_path FROM sys_file_resource WHERE id = #{id}
</select>
<!--项目分类统计-->
<select id="getProClassifyStatisticsList"
resultType="com.bonus.imgTool.backstage.entity.ProClassifyStatisticsVo">
SELECT COUNT(1) AS totalNum,
COUNT(IF(tcq.upload_type = '1', 1, NULL)) AS safetyVioNum,
COUNT(IF(tcq.upload_type = '2', 1, NULL)) AS qualityInsNum,
COUNT(IF(tcq.upload_type = '3', 1, NULL)) AS safetyMeasNum,
COUNT(IF(tcq.upload_type = '4', 1, NULL)) AS coordinatedPhotoNum,
COUNT(IF(tcq.upload_type = '5', 1, NULL)) AS importIssuesAndPublicityNum,
tp.name AS proName,
tcq.pro_id AS proId,
MAX(sfr.create_time) AS lastUpdateTime
FROM tb_comprehensive_query tcq
LEFT JOIN tb_project tp ON tcq.pro_id = tp.id
LEFT JOIN sys_file_resource sfr ON tcq.id = sfr.source_id AND tcq.upload_type = sfr.upload_type AND sfr.is_active = '1'
<where>
<if test="roleLevel = 0 and proIds != null and proIds.size() > 0">
AND tcq.pro_id IN
<foreach collection="proIds" item="proId" open="(" separator="," close=")">
#{proId}
</foreach>
</if>
<if test="id!=null">
AND tcq.pro_id = #{id}
</if>
AND tcq.is_active = '1'
</where>
GROUP BY tcq.upload_type, tcq.pro_id
</select>
<!--收藏/取消收藏图片-->
<update id="collectData">
<if test="collectType == 1">

View File

@ -5,12 +5,14 @@ layui.use(['form', 'layer', 'table'], function () {
layer = layui.layer;
table = layui.table;
layui.form.render();
let pros = getProsSelect();
setSelectValueName(pros,'proId','请选择工程');
pages(1, 10, 1);
})
function pages(pageNum, pageSize, typeNum) {
let params = getReqParams(pageNum, pageSize, typeNum);
let url = dataUrl + "/users/getList"
let url = dataUrl + "/backstage/synthesisQuery/getProClassifyStatisticsList"
ajaxRequest(url, "POST", params, true, function () {
}, function (result) {
console.log(result);
@ -65,48 +67,48 @@ function initTable(dataList, limit, page) {
return (page - 1) * limit + d.LAY_NUM;
}
},
{field: "loginName", title: "项目名称", width: "23%", unresize: true, align: "center"},
{field: "proName", title: "项目名称", width: "21%", unresize: true, align: "center"},
{
field: "username", title: "总照片数量", width: "8%", unresize: true, align: "center",
field: "totalNum", title: "总照片数量", width: "8%", unresize: true, align: "center",
templet: function (d) {
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",0)'><span style='color:#409EFF;'>0</span></div>";
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",0)'><span style='color:#409EFF;'>"+d.totalNum+"</span></div>";
}
},
{
field: "username", title: "安全违章", width: "8%", unresize: true, align: "center",
field: "safetyVioNum", title: "安全违章", width: "8%", unresize: true, align: "center",
templet: function (d) {
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",1)'><span style='color:#F56C6C;'>0</span></div>";
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",1)'><span style='color:#F56C6C;'>"+d.safetyVioNum+"</span></div>";
}
},
{
field: "username", title: "质量检查", width: "8%", unresize: true, align: "center",
field: "qualityInsNum", title: "质量检查", width: "8%", unresize: true, align: "center",
templet: function (d) {
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",2)'><span style='color:#80E1BB;'>0</span></div>";
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",2)'><span style='color:#80E1BB;'>"+d.qualityInsNum+"</span></div>";
}
},
{
field: "username", title: "安全措施落实", width: "10%", unresize: true, align: "center",
field: "safetyMeasNum", title: "安全措施落实", width: "10%", unresize: true, align: "center",
templet: function (d) {
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",3)'><span style='color:#FFC328;'>0</span></div>";
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",3)'><span style='color:#FFC328;'>"+d.safetyMeasNum+"</span></div>";
}
},
{
field: "username", title: "协调照片 ", width: "8%", unresize: true, align: "center",
field: "coordinatedPhotoNum", title: "协调照片 ", width: "8%", unresize: true, align: "center",
templet: function (d) {
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",4)'><span style='color:#F56CCF;'>0</span></div>";
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",4)'><span style='color:#F56CCF;'>"+d.coordinatedPhotoNum+"</span></div>";
}
},
{
field: "username", title: "重要事项及宣传 ", width: "10%", unresize: true, align: "center",
field: "importIssuesAndPublicityNum", title: "重要事项及宣传 ", width: "10%", unresize: true, align: "center",
templet: function (d) {
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",5)'><span style='color:#06B6D4;'>0</span></div>";
return "<div class='num-btn' onclick='viewImg("+JSON.stringify(d)+",5)'><span style='color:#06B6D4;'>"+d.importIssuesAndPublicityNum+"</span></div>";
}
},
{
field: "createTime", title: "最后更新时间", width: "10%", align: "center", templet: 'center',
field: "lastUpdateTime", title: "最后更新时间", width: "14%", align: "center", templet: 'center',
},
{
title: "操作", unresize: true, width: "10%", align: "center",
title: "操作", unresize: true, width: "8%", align: "center",
templet: function (d) {
let html = '';
let view = "<a class='layui-icon layui-icon-file' style='cursor:pointer;' title='详情' onclick='viewData("+JSON.stringify(d)+")'></a>"
@ -133,16 +135,16 @@ function getReqParams(page, limit, type) {
let obj = {};
if (!type) {
obj = {
page: page + "",
limit: limit + "",
keyWord: $('#keyWord').val(),
pageNum: page + "",
pageSize: limit + "",
id: $('#proId').val(),
};
} else {
obj = {
page: '1',
limit: '10',
keyWord: '',
pageNum: '1',
pageSize: '10',
id: '',
};
}
obj = {
@ -154,14 +156,12 @@ function getReqParams(page, limit, type) {
// 查询/重置
function query(type) {
pageNum = 1;
if(type === 2){
$('#proId').val('');
layui.form.render();
}
pages(1, limitSize);
}
//重置
function reset() {
pages(1, limitSize, 1)
}
/**详情*/
function viewData(obj){
openIframeByParamObj("viewData", "详情", "./proClassifyStatisticsDetail.html", "92%", "95%", obj);
@ -172,3 +172,35 @@ function viewImg(obj,type){
obj.type = type;
openIframeByParamObj("viewImg", "图片详情", "./photoView.html", "92%", "85%", obj);
}
/*下载*/
function downloadExcel(){
let obj = {
id: $('#proId').val()
}
let params = {
encryptedData: encryptCBC(JSON.stringify(obj))
}
let loadingMsg = layer.msg("数据导出中,请稍候...", {icon: 16, scrollbar: false, time: 0,});
let url = dataUrl + "/backstage/synthesisQuery/downloadExcel?token=" + tokens + "&encryptedData=" + encodeURIComponent(encryptCBC(JSON.stringify(obj)));
let xhr = new XMLHttpRequest();
xhr.open("post", url, true);
xhr.responseType = "blob"; // 转换流
xhr.setRequestHeader('Content-Type','application/json;charset=UTF-8')
xhr.onload = function () {
layer.close(loadingMsg);
if (this.status === 200) {
let blob = this.response;
var a = document.createElement("a");
var url = window.URL.createObjectURL(blob);
a.href = url;
a.download = "项目分类统计" + ".xlsx"; // 文件名
} else {
layer.msg("数据导出发生异常,请稍后重试", {icon: 16, scrollbar: false, time: 2000});
}
a.click();
window.URL.revokeObjectURL(url);
};
// xhr.send(params);
xhr.send();
}

View File

@ -9,6 +9,7 @@
<script src="../../js/layui-v2.9.14/layui/layui.js" charset="UTF-8" type="text/javascript"></script>
<script src="../../js/publicJs.js"></script>
<script src="../../js/commonUtils.js"></script>
<script src="../../js/select.js"></script>
<script src="../../js/openIframe.js"></script>
<script src="../../js/my/aes.js"></script>
<script src="../../js/ajaxRequest.js"></script>
@ -19,22 +20,22 @@
<div class="basic-search-box layout">
<form class="layui-form basic-form" onsubmit="return false;">
<div class="layui-form-item">
<div class="layui-inline" style="padding: 0 0 0 10px;">
<!--<div class="layui-inline" style="padding: 0 0 0 10px;">
<div class="layui-input-inline">
<select class="layui-select" lay-search placeholder="请选择工程类型"></select>
</div>
</div>
</div>-->
<div class="layui-inline" style="padding: 0 0 0 10px;">
<div class="layui-input-inline">
<select class="layui-select" lay-search placeholder="请选择工程"></select>
<select class="layui-select" id="proId" lay-search></select>
</div>
</div>
<div class="layui-inline btns">
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm btn-1" onclick="query(1)">查询
</button>
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm btn-1" onclick="reset()">重置
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm btn-1" onclick="query(2)">重置
</button>
<button type="button" class="layui-btn layui-btn-primary layui-btn-sm" onclick="reset()">导出
<button type="button" class="layui-btn layui-btn-primary layui-btn-sm" onclick="downloadExcel()">导出
</button>
</div>
</div>