diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.java index dfd93f6..cde2b12 100644 --- a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.java +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.java @@ -1,9 +1,6 @@ package net.lab1024.sa.admin.module.service.controller; -import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsAddForm; -import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsQueryForm; -import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsUpdateForm; -import net.lab1024.sa.admin.module.service.domain.form.LawyerStatisticsQueryForm; +import net.lab1024.sa.admin.module.service.domain.form.*; import net.lab1024.sa.admin.module.service.domain.vo.LawyerStatisticsVO; import net.lab1024.sa.admin.module.service.domain.vo.ServiceApplicationsVO; import net.lab1024.sa.admin.module.service.service.ServiceApplicationsService; @@ -116,4 +113,11 @@ public class ServiceApplicationsController { public ResponseDTO> getLawyerStatistics(@RequestBody @Valid LawyerStatisticsQueryForm queryForm) { return ResponseDTO.ok(serviceApplicationsService.getLawyerStatistics(queryForm)); } + + @Operation(summary = "律师统计信息导出 @author wzh") + @GetMapping("/serviceApplications/exportLawyer") + @SaCheckPermission("serviceApplications:exportLawyer") + public void exportLawyer(ServiceLawyerQueryForm queryForm, HttpServletResponse response) { + serviceApplicationsService.exportLawyer(queryForm, response); + } } diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.java index dd96787..9993b7b 100644 --- a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.java +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.java @@ -4,6 +4,8 @@ import java.util.List; import net.lab1024.sa.admin.module.service.domain.entity.ServiceApplicationsEntity; import net.lab1024.sa.admin.module.service.domain.form.LawyerStatisticsQueryForm; import net.lab1024.sa.admin.module.service.domain.form.ServiceApplicationsQueryForm; +import net.lab1024.sa.admin.module.service.domain.form.ServiceLawyerImportForm; +import net.lab1024.sa.admin.module.service.domain.form.ServiceLawyerQueryForm; import net.lab1024.sa.admin.module.service.domain.vo.LawyerStatisticsVO; import net.lab1024.sa.admin.module.service.domain.vo.ServiceApplicationsVO; import com.baomidou.mybatisplus.core.mapper.BaseMapper; @@ -50,12 +52,12 @@ public interface ServiceApplicationsDao extends BaseMapper getLawyerStatistics(); /** - * 律师统计查询(带参数) + * 律师统计查询(带参数)无分页 */ - List getLawyerStatisticsWithParam(Page page, @Param("queryForm") LawyerStatisticsQueryForm queryForm); + List getLawyerStatisticsWithParam(@Param("queryForm") ServiceLawyerQueryForm queryForm); /** - * 年度律师统计查询(带参数) + * 年度律师统计查询(带参数)有分页 */ List getLawyerStatisticsWithParamYear(Page page, @Param("queryForm") LawyerStatisticsQueryForm queryForm); diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceLawyerImportForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceLawyerImportForm.java new file mode 100644 index 0000000..d8ae35b --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceLawyerImportForm.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.service.domain.form; + +import cn.idev.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 律所统计报表导出表单 + * + * @Author wzh + * @Date 2025-12-22 + * @Copyright 1.0 + */ +@Data +public class ServiceLawyerImportForm { + private Long userId; + //@ExcelProperty("序号") + private Integer id; + + @ExcelProperty("执业律师") + private String lawyerName; + + @ExcelProperty("执业证号") + private String certificateNumber; + + @ExcelProperty("季度累计服务时长") + private Double quarterlyServiceDuration = 0.0; + + @ExcelProperty("季度累计服务成本") + private BigDecimal quarterlyServiceCost = BigDecimal.ZERO; + + @ExcelProperty("年度累计服务时长") + private Double annualServiceDuration = 0.0; + + @ExcelProperty("年度累计服务成本") + private BigDecimal annualServiceCost = BigDecimal.ZERO; + + //@ExcelProperty("备注") + private String mark; +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceLawyerQueryForm.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceLawyerQueryForm.java new file mode 100644 index 0000000..50ee7cf --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/domain/form/ServiceLawyerQueryForm.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.service.domain.form; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import net.lab1024.sa.base.common.domain.PageParam; + +/** + * 律师统计查询表单 + * + * @author wzh + */ +@Data +@Schema(description = "律师统计查询表单") +public class ServiceLawyerQueryForm { + + @Schema(description = "季度,1,2,3,4") + private Integer quarter; + + @Schema(description = "年度,格式:yyyy") + private Integer year; + + @Schema(description = "律师姓名") + private String lawyerName; + + @Schema(description = "律所名称") + private String firmName; + + @Schema(description = "开始时间") + private String startTime; + + @Schema(description = "结束时间") + private String endTime; + + private Long userId; +} \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.java b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.java index 740f1d1..1794e98 100644 --- a/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.java +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.java @@ -2,7 +2,9 @@ package net.lab1024.sa.admin.module.service.service; import cn.idev.excel.FastExcel; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.handler.SheetWriteHandler; +import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -29,6 +31,7 @@ import net.lab1024.sa.admin.module.system.department.service.DepartmentService; import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; import net.lab1024.sa.admin.util.AdminRequestUtil; +import net.lab1024.sa.admin.util.CellStyleStrategy; import net.lab1024.sa.admin.util.DateTimeUtil; import net.lab1024.sa.base.common.domain.PageResult; import net.lab1024.sa.base.common.domain.RequestUser; @@ -48,6 +51,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.time.LocalDateTime; @@ -604,30 +608,115 @@ public class ServiceApplicationsService { //统计当前年度的 List lawyerStatisticsWithParamYear = serviceApplicationsDao.getLawyerStatisticsWithParamYear(page, queryForm); PageResult lawyerStatisticsVOPageResult = SmartPageUtil.convert2PageResult(page, lawyerStatisticsWithParamYear); - //在统计月度的 - if (queryForm.getQuarter() == null) { - //获取当前月份上一季度的开始时间和结束时间 - String quarterStart = DateTimeUtil.getStartQuarter().getStartTime(); - String quarterEnd = DateTimeUtil.getStartQuarter().getEndTime(); - queryForm.setStartTime(quarterStart.toString()); - queryForm.setEndTime(quarterEnd.toString()); - } else{ - //根据季度获取季度的开发时间和 - LocalDateTime quarterStart = DateTimeEnum.getQuarterStart(queryForm.getYear(), queryForm.getQuarter()); - //结束时间 - LocalDateTime quarterEnd = DateTimeEnum.getQuarterEnd(queryForm.getYear(), queryForm.getQuarter()); - queryForm.setStartTime(quarterStart.toString()); - queryForm.setEndTime(quarterEnd.toString()); + if (!lawyerStatisticsVOPageResult.getList().isEmpty()) { + monthStatistics(queryForm, lawyerStatisticsVOPageResult.getList(),null); } + return lawyerStatisticsVOPageResult; + } - if (!lawyerStatisticsVOPageResult.getList().isEmpty()) { - for (LawyerStatisticsVO statisticsVO : lawyerStatisticsVOPageResult.getList()) { + /** + * 导出律师统计信息 + * @param queryForm + */ + public void exportLawyer(ServiceLawyerQueryForm queryForm, HttpServletResponse response) { + //根据year拼接年度的开始时间和结束时间 + String yearStart = DateTimeUtil.getYearStartAndEnd().getStartTime(); + String yearEnd = DateTimeUtil.getYearStartAndEnd().getEndTime(); + queryForm.setStartTime(yearStart); + queryForm.setEndTime(yearEnd); + List lawyerStatisticsWithParamYear = serviceApplicationsDao.getLawyerStatisticsWithParam(queryForm); + if (!lawyerStatisticsWithParamYear.isEmpty()) { + LawyerStatisticsQueryForm queryForm1 = SmartBeanUtil.copy(queryForm, LawyerStatisticsQueryForm.class); + monthStatistics(queryForm1, null, lawyerStatisticsWithParamYear); + } + //写入数据到文件 + exportExcel(response, "律师统计信息.xlsx", "律师统计信息", ServiceLawyerImportForm.class, lawyerStatisticsWithParamYear); + } + + + /** + * 统计月度的工作时长 + * @param originalQueryForm + * @param lawyerStatisticsVOPageResult + */ + public void monthStatistics(LawyerStatisticsQueryForm originalQueryForm, List lawyerStatisticsVOPageResult,List lawyerStatisticsWithParamYear) { + if (lawyerStatisticsVOPageResult != null) { + for (LawyerStatisticsVO statisticsVO : lawyerStatisticsVOPageResult) { + // 创建新的查询表单对象以避免修改原始对象 + LawyerStatisticsQueryForm queryForm = SmartBeanUtil.copy(originalQueryForm, LawyerStatisticsQueryForm.class); + if (queryForm.getQuarter() == null) { + //获取当前月份上一季度的开始时间和结束时间 + String quarterStart = DateTimeUtil.getStartQuarter().getStartTime(); + String quarterEnd = DateTimeUtil.getStartQuarter().getEndTime(); + queryForm.setStartTime(quarterStart.toString()); + queryForm.setEndTime(quarterEnd.toString()); + } else{ + //根据季度获取季度的开发时间和 + LocalDateTime quarterStart = DateTimeEnum.getQuarterStart(queryForm.getYear(), queryForm.getQuarter()); + //结束时间 + LocalDateTime quarterEnd = DateTimeEnum.getQuarterEnd(queryForm.getYear(), queryForm.getQuarter()); + queryForm.setStartTime(quarterStart.toString()); + queryForm.setEndTime(quarterEnd.toString()); + } + queryForm.setUserId(statisticsVO.getUserId()); + //季度服务时间范围 + LawyerStatisticsVO quarterStatisticsVO = serviceApplicationsDao.getLawyerStatistic(queryForm); + if (quarterStatisticsVO != null && quarterStatisticsVO.getQuarterlyServiceDuration() != null) { + statisticsVO.setQuarterlyServiceDuration(quarterStatisticsVO.getQuarterlyServiceDuration()); + } + } + }else if (lawyerStatisticsWithParamYear != null) { + for (ServiceLawyerImportForm statisticsVO : lawyerStatisticsWithParamYear) { + // 创建新的查询表单对象以避免修改原始对象 + LawyerStatisticsQueryForm queryForm = SmartBeanUtil.copy(originalQueryForm, LawyerStatisticsQueryForm.class); + if (queryForm.getQuarter() == null) { + //获取当前月份上一季度的开始时间和结束时间 + String quarterStart = DateTimeUtil.getStartQuarter().getStartTime(); + String quarterEnd = DateTimeUtil.getStartQuarter().getEndTime(); + queryForm.setStartTime(quarterStart.toString()); + queryForm.setEndTime(quarterEnd.toString()); + } else{ + //根据季度获取季度的开发时间和 + LocalDateTime quarterStart = DateTimeEnum.getQuarterStart(queryForm.getYear(), queryForm.getQuarter()); + //结束时间 + LocalDateTime quarterEnd = DateTimeEnum.getQuarterEnd(queryForm.getYear(), queryForm.getQuarter()); + queryForm.setStartTime(quarterStart.toString()); + queryForm.setEndTime(quarterEnd.toString()); + } queryForm.setUserId(statisticsVO.getUserId()); //季度服务时间范围 LawyerStatisticsVO quarterStatisticsVO = serviceApplicationsDao.getLawyerStatistic(queryForm); - statisticsVO.setQuarterlyServiceDuration(quarterStatisticsVO.getQuarterlyServiceDuration()); + if (quarterStatisticsVO != null && quarterStatisticsVO.getQuarterlyServiceDuration() != null) { + statisticsVO.setQuarterlyServiceDuration(quarterStatisticsVO.getQuarterlyServiceDuration()); + } } } - return lawyerStatisticsVOPageResult; + } + /** + * 通用Excel导出功能 + * @param response HttpServletResponse + * @param fileName 文件名 + * @param sheetName 工作表名 + * @param clazz Excel实体类 + * @param data 数据列表 + */ + public void exportExcel(HttpServletResponse response, String fileName, String sheetName, Class clazz, List data) { + try { + // 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + // 正确设置Content-Disposition响应头,解决中文文件名问题 + String encodedFileName = java.net.URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); + response.setHeader("Content-disposition", "attachment; filename*=UTF-8''" + encodedFileName); + + EasyExcel.write(response.getOutputStream(), clazz) + .autoCloseStream(false) + .registerWriteHandler(CellStyleStrategy.styleStrategy()) + .sheet(sheetName) + .doWrite(data); + } catch (IOException e) { + log.error("Excel导出失败", e); + throw new BusinessException("Excel导出失败:" + e.getMessage()); + } } } \ No newline at end of file diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/util/CellStyleStrategy.java b/yun-admin/src/main/java/net/lab1024/sa/admin/util/CellStyleStrategy.java new file mode 100644 index 0000000..7f66b5d --- /dev/null +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/util/CellStyleStrategy.java @@ -0,0 +1,61 @@ +package net.lab1024.sa.admin.util; + +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +/** + * @program: yun-parent + * @description: + * @author: Mr.Wang + * @create: 2025-12-25 15:50 + **/ +public class CellStyleStrategy { + /** + * 设置表头和内容样式 + */ + + public static HorizontalCellStyleStrategy styleStrategy() { + //表头样式策略 + WriteCellStyle headWriteCellStyle = new WriteCellStyle(); + //设置表头居中对齐 + headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + + headWriteCellStyle.setLeftBorderColor(IndexedColors.GREY_25_PERCENT.index); + headWriteCellStyle.setRightBorderColor(IndexedColors.GREY_25_PERCENT.index); + headWriteCellStyle.setBottomBorderColor(IndexedColors.GREY_25_PERCENT.index); + headWriteCellStyle.setTopBorderColor(IndexedColors.GREY_25_PERCENT.index); + + WriteFont headWriteFont = new WriteFont(); + headWriteFont.setBold(false); + headWriteFont.setFontName("Arial"); + headWriteFont.setFontHeightInPoints((short) 10); + headWriteCellStyle.setWriteFont(headWriteFont); + + //2 内容样式策略 + WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); + WriteFont contentWriteFont = new WriteFont(); + //内容大小 + contentWriteFont.setFontName("Arial"); + contentWriteFont.setFontHeightInPoints((short) 10); + contentWriteCellStyle.setWriteFont(contentWriteFont); + +// //设置自动换行 +// contentWriteCellStyle.setWrapped(true); +// //设置垂直居中 +// contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); +// //头默认了FillPatternType所以可以不指定 +// contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); +// //设置水平居中 +// contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); +// +// //设置边框样式 +// contentWriteCellStyle.setBorderLeft(BorderStyle.THIN); +// contentWriteCellStyle.setBorderTop(BorderStyle.THIN); +// contentWriteCellStyle.setBorderRight(BorderStyle.THIN); +// contentWriteCellStyle.setBorderBottom(BorderStyle.THIN); + + return new HorizontalCellStyleStrategy(headWriteCellStyle,contentWriteCellStyle); + } +} diff --git a/yun-admin/src/main/java/net/lab1024/sa/admin/util/DateTimeUtil.java b/yun-admin/src/main/java/net/lab1024/sa/admin/util/DateTimeUtil.java index 5b15261..e8f0ae4 100644 --- a/yun-admin/src/main/java/net/lab1024/sa/admin/util/DateTimeUtil.java +++ b/yun-admin/src/main/java/net/lab1024/sa/admin/util/DateTimeUtil.java @@ -76,13 +76,6 @@ public class DateTimeUtil { LocalDate beginOfYear = currentDate.withDayOfYear(1); LocalDate endOfYear = currentDate.withDayOfYear(currentDate.lengthOfYear()); - //格式化 - //DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"); - - // 输出上个季度的起始和结束日期 - //String startTime = beginOfYear.format(formatter); - //String endTime = endOfYear.format(formatter); - timeVo.setYearStart(beginOfYear.toString()); timeVo.setYearEnd(endOfYear.toString()); return timeVo; diff --git a/yun-admin/src/main/resources/mapper/service/ServiceApplicationsMapper.xml b/yun-admin/src/main/resources/mapper/service/ServiceApplicationsMapper.xml index 2b47f4f..8e84fc0 100644 --- a/yun-admin/src/main/resources/mapper/service/ServiceApplicationsMapper.xml +++ b/yun-admin/src/main/resources/mapper/service/ServiceApplicationsMapper.xml @@ -122,12 +122,12 @@ - SELECT e.actual_name AS lawyerName, e.employee_id as userId, tsa.certificate_number AS certificateNumber, - COALESCE(SUM(tsa.service_duration), 0) AS quarterlyServiceDuration + COALESCE(SUM(tsa.service_duration), 0) AS annualServiceDuration FROM t_service_applications tsa LEFT JOIN t_employee e ON tsa.user_id = e.employee_id LEFT JOIN t_department d ON tsa.firm_id = d.department_id diff --git a/yun-admin/target/classes/mapper/service/ServiceApplicationsMapper.xml b/yun-admin/target/classes/mapper/service/ServiceApplicationsMapper.xml index 2b47f4f..8e84fc0 100644 --- a/yun-admin/target/classes/mapper/service/ServiceApplicationsMapper.xml +++ b/yun-admin/target/classes/mapper/service/ServiceApplicationsMapper.xml @@ -122,12 +122,12 @@ - SELECT e.actual_name AS lawyerName, e.employee_id as userId, tsa.certificate_number AS certificateNumber, - COALESCE(SUM(tsa.service_duration), 0) AS quarterlyServiceDuration + COALESCE(SUM(tsa.service_duration), 0) AS annualServiceDuration FROM t_service_applications tsa LEFT JOIN t_employee e ON tsa.user_id = e.employee_id LEFT JOIN t_department d ON tsa.firm_id = d.department_id diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.class index 69a909f..52155a4 100644 Binary files a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.class and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/controller/ServiceApplicationsController.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.class index 4833ba0..b378fec 100644 Binary files a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.class and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/dao/ServiceApplicationsDao.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.class index b16fc18..4c1b922 100644 Binary files a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.class and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/domain/entity/ServiceApplicationsEntity.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService$DropdownSheetWriteHandler.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService$DropdownSheetWriteHandler.class index fde7888..763868a 100644 Binary files a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService$DropdownSheetWriteHandler.class and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService$DropdownSheetWriteHandler.class differ diff --git a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.class b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.class index 7a9ce44..aa2ee6e 100644 Binary files a/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.class and b/yun-admin/target/classes/net/lab1024/sa/admin/module/service/service/ServiceApplicationsService.class differ