无关风月
10 天以前 a1eabf01b3dbec288897d4d1cc400cfdad076d1f
Merge remote-tracking branch 'origin/master'
2个文件已添加
6个文件已修改
571 ■■■■■ 已修改文件
ruoyi-admin/pom.xml 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ReportController.java 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/pom.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/utils/ExcelPoiUtils.java 333 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/LocationTypeListByProjectVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/ProjectDeptDetailsChildVO.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/ProjectDeptDetailsVO.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/TaskSummaryVO.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml
@@ -148,16 +148,16 @@
        <!-- excel工具 -->
        <!-- Apache POI核心依赖 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.apache.poi</groupId>-->
<!--            <artifactId>poi</artifactId>-->
<!--            <version>3.17</version>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>org.apache.poi</groupId>-->
<!--            <artifactId>poi-ooxml</artifactId>-->
<!--            <version>3.17</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>net.coobird</groupId>
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ReportController.java
@@ -16,6 +16,7 @@
import com.ruoyi.system.model.*;
import com.ruoyi.system.query.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.ExcelPoiUtils;
import com.ruoyi.system.vo.system.*;
import com.ruoyi.web.util.OssUploadUtil;
import io.swagger.annotations.Api;
@@ -479,7 +480,6 @@
                    locationTypeListByProjectVOS1.add(temp);
                }
                projectDeptDetailsChildVO.setLocationTypeList(locationTypeListByProjectVOS1);
                projectDeptDetailsChildVO.setCleanerCount(0);
            }
@@ -631,7 +631,6 @@
    @ApiOperation(value = "巡检人员报表")
    @PostMapping(value = "/patrolInspectorList")
    public R<List<PatrolInspectorVO>> patrolInspectorList(@RequestBody PatrolInspectorQuery query) {
        List<SysUser> sysUsers = sysUserService.selectAllList();
        LambdaQueryWrapper<TLeave> tLeaveLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -1075,5 +1074,140 @@
            }
        }
    }
    @ApiOperation(value = "任务报表导出模板")
    @PostMapping(value = "/exportExcel")
    public void exportExcel(@RequestBody TaskDetailsQuery query,HttpServletResponse response) throws Exception{
        // 动态标头名称字段
        final String headerName = "locationTypeName";
        // 动态标头值字段
        final String headerValue = "locationNum";
        List<TLocationType> locationTypeList = locationTypeService.list();
        List<TLocation> locations = locationService.list();
        LambdaQueryWrapper<TTask> tTaskLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasLength(query.getStartTime()) && StringUtils.hasLength(query.getEndTime())) {
            tTaskLambdaQueryWrapper.ge(TTask::getImplementTime, query.getStartTime());
            tTaskLambdaQueryWrapper.le(TTask::getImplementTime, query.getEndTime());
        }
        List<ProjectDeptDetailsVO> res = new ArrayList<>();
        List<TTask> tasks = taskCleanerService.list(tTaskLambdaQueryWrapper);
        List<TTaskDetail> taskDetails = taskDetailService.lambdaQuery().orderByDesc(BaseModel::getCreateTime).list();
        List<String> collect = tasks.stream().map(TTask::getProjectId).distinct().collect(Collectors.toList());
        List<TProjectDept> projectDepts = projectDeptService.list();
        List<String> strings = new ArrayList<>();
        // 片区ids 反查项目部
        List<TProjectDept> list1 = projectDeptService.lambdaQuery().in(TProjectDept::getId, collect).list();
        for (TProjectDept tProjectDept : list1) {
            TProjectDept tProjectDept1 = projectDepts.stream().filter(e -> e.getId().equals(tProjectDept.getParentId())).findFirst().orElse(null);
            if (tProjectDept1 != null && !strings.contains(tProjectDept1.getId())) {
                ProjectDeptDetailsVO projectDeptDetailsVO = new ProjectDeptDetailsVO();
                projectDeptDetailsVO.setProjectName(tProjectDept1.getProjectName());
                List<TProjectDept> collect1 = list1.stream().filter(e -> e.getParentId().equals(tProjectDept1.getId())).collect(Collectors.toList());
                List<ProjectDeptDetailsChildVO> projectDeptDetailsChildVOS = new ArrayList<>();
                for (TProjectDept projectDept : collect1) {
                    ProjectDeptDetailsChildVO projectDeptDetailsChildVO = new ProjectDeptDetailsChildVO();
                    projectDeptDetailsChildVO.setProjectChildName(projectDept.getProjectName());
                    projectDeptDetailsChildVO.setProjectId(projectDept.getId());
                    projectDeptDetailsChildVOS.add(projectDeptDetailsChildVO);
                }
                projectDeptDetailsVO.setProjectChild(projectDeptDetailsChildVOS);
                res.add(projectDeptDetailsVO);
                strings.add(tProjectDept1.getId());
            }
        }
        List<LocationTypeListByProjectVO> locationTypeListByProjectVOS = new ArrayList<>();
        for (TLocationType tLocationType : locationTypeList) {
            LocationTypeListByProjectVO locationTypeListByProjectVO = new LocationTypeListByProjectVO();
            locationTypeListByProjectVO.setLocationTypeName(tLocationType.getLocationName());
            locationTypeListByProjectVO.setLocationNum(0);
            locationTypeListByProjectVO.setId(tLocationType.getId());
            locationTypeListByProjectVOS.add(locationTypeListByProjectVO);
        }
        for (ProjectDeptDetailsVO re : res) {
            List<ProjectDeptDetailsChildVO> projectChild = re.getProjectChild();
            for (ProjectDeptDetailsChildVO projectDeptDetailsChildVO : projectChild) {
                int cleanerCount = cleanerService.lambdaQuery().eq(TCleaner::getProjectId, projectDeptDetailsChildVO.getProjectId()).list().size();
                projectDeptDetailsChildVO.setCleanerCount(cleanerCount);
                for (LocationTypeListByProjectVO locationTypeListByProjectVO : locationTypeListByProjectVOS) {
                    List<TaskSummaryVO> taskSummaryVOS = new ArrayList<>();
                    List<String> locationIds = locations.stream().filter(e -> e.getLocationType().equals(locationTypeListByProjectVO.getId())).map(TLocation::getId).collect(Collectors.toList());
                    if (locationIds.isEmpty()) {
                        locationTypeListByProjectVO.setLocationNum(0);
                    } else {
                        List<TTask> taskList = tasks.stream().filter(e -> e.getProjectId().equals(projectDeptDetailsChildVO.getProjectId())
                                && locationIds.contains(e.getLocationId())).collect(Collectors.toList());
                        Integer count = taskList.size();
                        locationTypeListByProjectVO.setLocationNum(count);
                        int total = taskList.size();
                        int num1 = 0;
                        int num2 = 0;
                        int num3 = 0;
                        int num4 = 0;
                        int num5 = 0;
                        int num6 = 0;
                        int num7 = 0;
                        TaskSummaryVO taskSummaryVO = new TaskSummaryVO();
                        for (TTask tTask : taskList) {
                            TTaskDetail tTaskDetail = taskDetails.stream().filter(e -> e.getTaskId().equals(tTask.getId()) && e.getClearStatus() != null).findFirst().orElse(null);
                            if (tTaskDetail!=null){
                                switch (tTaskDetail.getClearStatus()) {
                                    case 1:
                                        num1++;
                                        break;
                                    case 2:
                                        num2++;
                                        break;
                                }
                            }
                            // 任务状态:1未执行、2超时、3待确认、4待整改、5整改完成、6已完成
                            switch (tTask.getStatus()) {
                                case 1:
                                    if (tTaskDetail == null) {
                                        num3++;
                                    }
                                    break;
                                case 2:
                                    num6++;
                                    break;
                                case 3:
                                    break;
                                case 4:
                                    num4++;
                                    break;
                                case 5:
                                    num7++;
                                    break;
                                case 6:
                                    num5++;
                                    break;
                            }
                        }
                        taskSummaryVO.setTotal(total);
                        taskSummaryVO.setNum1(num1);
                        taskSummaryVO.setNum2(num2);
                        taskSummaryVO.setNum3(num3);
                        taskSummaryVO.setNum4(num4);
                        taskSummaryVO.setNum5(num5);
                        taskSummaryVO.setNum6(num6);
                        taskSummaryVO.setNum7(num7);
                        taskSummaryVOS.add(taskSummaryVO);
                    }
                    projectDeptDetailsChildVO.setTaskSummaryVOS(taskSummaryVOS);
                }
                projectDeptDetailsChildVO.setLocationTypeList(locationTypeListByProjectVOS);
            }
        }
        try {
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));
            ExcelPoiUtils.exportExcel(response,  "任务报表_"+time, "任务报表导出模板",
                    "sheet", res, headerName, headerValue);
        } catch (Exception e) {
            System.out.println("导出错误,"+e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
    }
}
ruoyi-system/pom.xml
@@ -41,17 +41,17 @@
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>3.0.3</version>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>3.0.3</version>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>3.0.3</version>
            <version>4.4.0</version>
        </dependency>
        <!--mybatis-plus-->
@@ -93,6 +93,12 @@
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83_noneautotype</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>
ruoyi-system/src/main/java/com/ruoyi/system/utils/ExcelPoiUtils.java
New file
@@ -0,0 +1,333 @@
package com.ruoyi.system.utils;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
 * @Author: 一杯美式
 * @version: V1.0
 * @Date: 2024-04-23 10:38
 * @Package: com.victory.jfe.pdm.srm.config
 */
@Slf4j
@Service
public class ExcelPoiUtils {
    /**
     * 动态列导出
     * @param response    响应
     * @param fileName    文件名
     * @param title       标题
     * @param sheetName   sheet名称
     * @param dataList    导出数据
     * @param headerName  动态列标题
     * @param headerValue 动态列值
     * @param <T>
     * @throws Exception
     */
    public static <T> void exportExcel(HttpServletResponse response, String fileName, String title, String sheetName,
                                       List<T> dataList, String headerName, String headerValue) throws Exception {
        if (CollectionUtils.isNotEmpty(dataList)) {
            T dataInstance = dataList.get(0);
            List<ExcelExportEntity> entityList = buildExcelExportEntityList(dataInstance, headerName, "");
            List<Object> objList = convertDataListToObjList(dataList, headerName,headerValue);
            downloadExcelEntityDynamic(response, entityList, objList, fileName, title, sheetName);
        }
    }
    public static <T> void exportExcel(HttpServletResponse response, String fileName, String title, String sheetName,
                                       List<T> dataList, String headerName, String headerValue, String ignoreCol) throws Exception {
        if (CollectionUtils.isNotEmpty(dataList)) {
            T dataInstance = dataList.get(0);
            List<ExcelExportEntity> entityList = buildExcelExportEntityList(dataInstance, headerName, ignoreCol);
            List<Object> objList = convertDataListToObjList(dataList, headerName,headerValue);
            downloadExcelEntityDynamic(response, entityList, objList, fileName, title, sheetName);
        }
    }
    /**
     * 构建Excel导出实体列表
     *
     * @param t          取数据集第一条数据 做实体列表构建
     * @param headerName 动态列标题
     * @param <T>        数据类型
     * @return Excel导出实体列表
     * @throws IllegalAccessException 如果无法访问字段
     */
    private static <T> List<ExcelExportEntity> buildExcelExportEntityList(T t, String headerName, String ignoreCol) throws IllegalAccessException {
        List<ExcelExportEntity> entityList = new ArrayList<>();
        Field[] fields = t.getClass().getDeclaredFields();
        int index = 0;
        for (Field field : fields) {
            field.setAccessible(true);
            Optional<Excel> excelOpt = Optional.ofNullable(field.getAnnotation(Excel.class));
            Optional<ExcelCollection> excelCollectionOpt = Optional.ofNullable(field.getAnnotation(ExcelCollection.class));
            if (excelOpt.isPresent()) {
                // 处理固定导出列
                if (ignoreCol.contains(field.getName())) {
                    index++;
                } else {
                    index = handleFixedExportColumn(entityList, field, excelOpt.get(), index);
                }
            } else if (excelCollectionOpt.isPresent() && List.class.isAssignableFrom(field.getType())) {
                // 处理自定义导出列
                index = handleCustomExportColumn(t, entityList, field, headerName, index);
            }
        }
        return entityList;
    }
    /**
     * 处理固定导出列
     *
     * @param entityList 实体列表
     * @param field      字段
     * @param excel      Excel注解
     * @param index      索引
     * @return 更新后的索引
     */
    private static int handleFixedExportColumn(List<ExcelExportEntity> entityList, Field field, Excel excel, int index) {
        Object name = AnnotationUtil.getAnnotationValue(field, Excel.class, "name");
        ExcelExportEntity entity = createExcelExportEntity(field, name.toString(), field.getName(), index);
        entityList.add(entity);
        return index + 1;
    }
    /**
     * 处理自定义导出列
     *
     * @param t          数据对象
     * @param entityList 实体列表
     * @param field      字段
     * @param headerName 动态列标题
     * @param index      索引
     * @param <T>        数据类型
     * @return 更新后的索引
     * @throws IllegalAccessException 如果无法访问字段
     */
    private static <T> int handleCustomExportColumn(T t, List<ExcelExportEntity> entityList, Field field, String headerName, int index) throws IllegalAccessException {
        List<?> dynamicColl = (List<?>) field.get(t);
        for (Object arr : dynamicColl) {
            Field[] typeFields = arr.getClass().getDeclaredFields();
            for (Field typeField : typeFields) {
                typeField.setAccessible(true);
                Excel excelItem = typeField.getAnnotation(Excel.class);
                if (excelItem != null && headerName.equals(typeField.getName())) {
                    Object value = typeField.get(arr);
                    ExcelExportEntity entity = createExcelExportEntity(typeField, value.toString(), value.toString(), index);
                    entityList.add(entity);
                    index++;
                }
            }
        }
        return index;
    }
    /**
     * 将数据对象列表转换为对象列表,通过异步处理每个项。
     *
     * @param dataList 需要处理的数据对象列表。
     * @param headerName 用于从对象中提取特定值的标题名称。
     * @param headerValue 用于从对象中提取特定值的标题值。
     * @param <T> 数据对象列表中的对象类型。
     * @return 表示处理过的数据对象的映射列表。
     */
    public static <T> List<Object> convertDataListToObjList(List<T> dataList, String headerName, String headerValue) {
        // 创建一个固定大小的线程池 =处理器数量
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        long start = System.currentTimeMillis();
        List<CompletableFuture<Object>> futures = new ArrayList<>();
        // 提交每个数据对象进行异步处理
        for (T data : dataList) {
            futures.add(CompletableFuture.supplyAsync(() -> processData(data, headerName, headerValue), executorService));
        }
        // 收集处理结果
        List<Object> objList = futures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
        // 关闭线程池
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(2, TimeUnit.MINUTES)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
        log.info("数据处理时间:" + (System.currentTimeMillis() - start) + "ms");
        return objList;
    }
    /**
     * 处理单个数据对象以提取相关字段及其值。
     *
     * @param data 要处理的数据对象。
     * @param headerName 用于从对象中提取特定值的标题名称。
     * @param headerValue 用于从对象中提取特定值的标题值。
     * @param <T> 数据对象的类型。
     * @return 表示数据对象的映射。
     */
    private static <T> Object processData(T data, String headerName, String headerValue) {
        Map<String, Object> dataMap = new HashMap<>();
        Field[] fields = ReflectUtil.getFields(data.getClass());
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                // 将字段名和值放入dataMap中
                dataMap.put(field.getName(), field.get(data));
                ExcelCollection excelCollection = field.getAnnotation(ExcelCollection.class);
                // 如果字段是ExcelCollection并且是List类型,进一步处理
                if (excelCollection != null && field.getType().getName().equals(List.class.getName())) {
                    List<?> dynamicColl = (List<?>) field.get(data);
                    for (Object arr : dynamicColl) {
                        String key = null;
                        String val = null;
                        Field[] typeFields = arr.getClass().getDeclaredFields();
                        for (Field typeField : typeFields) {
                            typeField.setAccessible(true);
                            Excel excelItem = typeField.getAnnotation(Excel.class);
                            // 根据注解提取key和value
                            if (excelItem != null) {
                                if (headerName.equals(typeField.getName())) {
                                    key = String.valueOf(typeField.get(arr));
                                } else if (headerValue.equals(typeField.getName())) {
                                    val = String.valueOf(typeField.get(arr));
                                }
                            }
                        }
                        dataMap.put(key, val);
                    }
                }
            } catch (IllegalAccessException e) {
                log.error("无法访问字段值:", e.getMessage());
                return null;
            }
        }
        return dataMap;
    }
    /**
     * 动态生成并下载Excel文件。
     *
     * @param response HttpServletResponse对象,用于发送响应。
     * @param entityList Excel导出实体列表。
     * @param list 数据列表。
     * @param fileName 文件名。
     * @param title 标题。
     * @param sheetName 工作表名称。
     * @throws Exception 可能抛出的异常。
     */
    public static void downloadExcelEntityDynamic(HttpServletResponse response, List<ExcelExportEntity> entityList,
                                                  List<Object> list, String fileName, String title,
                                                  String sheetName) throws Exception {
        setResponseHeadersForDownload1(response, fileName);
        ExportParams exportParams = StringUtils.hasText(title) ? new ExportParams(title, sheetName) : new ExportParams();
        if (!StringUtils.hasText(title)) {
            exportParams.setSheetName(sheetName);
        }
        int pageSize = 12000;
        int totalPages = (list.size() + pageSize - 1) / pageSize;
        Workbook workbook = ExcelExportUtil.exportBigExcel(exportParams, entityList, (obj, page) -> {
            if (((int) obj) < page) {
                return null;
            }
            log.info("当前查询第{}页数据", page);
            int fromIndex = (page - 1) * pageSize;
            int toIndex = Math.min(page * pageSize, list.size());
            return list.subList(fromIndex, toIndex);
        }, totalPages);
        try (ServletOutputStream output = response.getOutputStream();
             BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output)) {
            workbook.write(bufferedOutPut);
            bufferedOutPut.flush();
        }
    }
    private static void setResponseHeadersForDownload1(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
    }
    public static void setResponseHeadersForDownload(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "utf-8"));
        response.setContentType("application/octet-stream;charset=utf-8");
    }
    /**
     * 将@Excel或者@ExcelCollection修饰的字段转为ExcelExportEntity
     */
    private static ExcelExportEntity createExcelExportEntity(Field typeField, String name, String key, int index) {
        Map<String, Object> annotationValueMap = AnnotationUtil.getAnnotationValueMap(typeField, Excel.class);
        ExcelExportEntity entity = JSONObject.parseObject(JSONObject.toJSONBytes(annotationValueMap), ExcelExportEntity.class);
        // 字段名和@Excel的name一致,视为动态表头列
        entity.setName(name);
        entity.setKey(key);
        entity.setOrderNum(index);
        return entity;
    }
    private static ExcelExportEntity createExcelExportEntity1(Field typeField, String name, String key, int index) {
        ExcelExportEntity entity = new ExcelExportEntity();
        // 设置基本信息
        entity.setName(name);
        entity.setKey(key);
        entity.setOrderNum(index);
        // 设置注解中的属性
        Excel excel = typeField.getAnnotation(Excel.class);
        if (excel != null) {
            try {
                BeanUtils.copyProperties(entity, excel); // 复制注解中的属性到ExcelExportEntity对象
            } catch (Exception e) {
                log.error(e.getMessage());
                throw new RuntimeException("无法从Excel注解复制属性:", e);
            }
        }
        return entity;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/LocationTypeListByProjectVO.java
@@ -1,5 +1,6 @@
package com.ruoyi.system.vo.system;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -11,8 +12,10 @@
public class LocationTypeListByProjectVO {
    @ApiModelProperty("类型名称")
    @Excel(name = "locationTypeName", width = 20)
    private String locationTypeName;
    @ApiModelProperty("数量")
    @Excel(name = "locationNum", width = 20)
    private Integer locationNum;
    @ApiModelProperty("类型id")
    private String id;
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/ProjectDeptDetailsChildVO.java
@@ -1,5 +1,7 @@
package com.ruoyi.system.vo.system;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import com.ruoyi.system.model.TProjectDept;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -12,14 +14,20 @@
@ApiModel(value = "片区VO")
public class ProjectDeptDetailsChildVO  {
    @ApiModelProperty("作业类型分类")
    private List<LocationTypeListByProjectVO> locationTypeList;
    @ApiModelProperty("片区名称")
    @Excel(name = "片区名称", width = 20)
    private String projectChildName;
    @ApiModelProperty("保洁员数量")
    @Excel(name = "巡检保洁员数", width = 20)
    private Integer cleanerCount;
    @ApiModelProperty("作业类型分类")
    @ExcelCollection(name = "作业类型分类")
    private List<LocationTypeListByProjectVO> locationTypeList;
    @ApiModelProperty("任务情况汇总")
    @ExcelCollection(name = "任务情况汇总")
    private List<TaskSummaryVO> taskSummaryVOS;
    @ApiModelProperty("片区id")
    private String projectId;
    @ApiModelProperty("保洁员数量")
    private Integer cleanerCount;
    @ApiModelProperty("总数")
    private Integer total;
    @ApiModelProperty("清洁合格")
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/ProjectDeptDetailsVO.java
@@ -1,5 +1,7 @@
package com.ruoyi.system.vo.system;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import com.ruoyi.system.model.TProjectDept;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -11,9 +13,11 @@
@ApiModel(value = "任务报表VO")
public class ProjectDeptDetailsVO  {
    @ApiModelProperty("片区")
    private List<ProjectDeptDetailsChildVO> projectChild;
    @ApiModelProperty("项目名称")
    @ApiModelProperty("项目")
    @Excel(name = "项目", width = 20,needMerge = true)
    private String projectName;
    @ApiModelProperty("片区")
    @ExcelCollection(name = "片区")
    private List<ProjectDeptDetailsChildVO> projectChild;
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/TaskSummaryVO.java
New file
@@ -0,0 +1,39 @@
package com.ruoyi.system.vo.system;
import cn.afterturn.easypoi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "任务情况汇总VO")
public class TaskSummaryVO implements Serializable {
    @ApiModelProperty("总数")
    @Excel(name = "总数")
    private Integer total;
    @ApiModelProperty("清洁合格")
    @Excel(name = "清洁合格")
    private Integer num1;
    @ApiModelProperty("清洁不合格")
    @Excel(name = "清洁不合格")
    private Integer num2;
    @ApiModelProperty("未执行任务")
    @Excel(name = "未执行任务")
    private Integer num3;
    @ApiModelProperty("待整改任务")
    @Excel(name = "待整改任务")
    private Integer num4;
    @ApiModelProperty("审核通过任务")
    @Excel(name = "审核通过任务")
    private Integer num5;
    @ApiModelProperty("超时未执行任务")
    @Excel(name = "超时未执行任务")
    private Integer num6;
    @ApiModelProperty("整改完成任务")
    @Excel(name = "整改完成任务")
    private Integer num7;
}