✨ 完善毛利分析筛选与导出日志

This commit is contained in:
caojia
2026-10-15 14:37:18 +08:00
parent be2a359698
commit c704021f2f
15 changed files with 534 additions and 39 deletions
@@ -1,23 +1,31 @@
package com.bms.web.controller.report;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
// 提成功能暂停使用:import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.bms.common.annotation.Log;
import com.bms.common.config.BmsConfig;
import com.bms.common.core.controller.BaseController;
import com.bms.common.core.domain.AjaxResult;
import com.bms.common.core.page.TableDataInfo;
import com.bms.common.enums.BusinessType;
import com.bms.common.exception.ServiceException;
import com.bms.common.utils.file.FileUtils;
import com.bms.common.utils.poi.ExcelUtil;
import com.bms.price.domain.PrcProfitCommissionRate;
// 提成功能暂停使用:import com.bms.price.domain.PrcProfitCommissionRate;
import com.bms.price.domain.PrcProfitReportExport;
import com.bms.price.domain.vo.PrcProfitReportOrderRow;
import com.bms.price.domain.vo.PrcProfitReportProductRow;
import com.bms.price.domain.vo.PrcProfitReportQuery;
@@ -39,6 +47,7 @@ public class PrcProfitReportController extends BaseController
return success(profitReportService.selectSummary(query));
}
/* 提成比例查询、维护、删除接口暂停使用,保留代码便于恢复。
@PreAuthorize("@ss.hasPermi('report:profit:commission:list')")
@GetMapping("/commission-rates")
public AjaxResult commissionRates()
@@ -62,6 +71,7 @@ public class PrcProfitReportController extends BaseController
{
return toAjax(profitReportService.deleteCommissionRate(rateId));
}
*/
@PreAuthorize("@ss.hasPermi('report:profit:list')")
@GetMapping("/orders")
@@ -84,20 +94,115 @@ public class PrcProfitReportController extends BaseController
@Log(title = "毛利报表-订单维度", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('report:profit:export')")
@PostMapping("/orders/export")
public void exportOrders(HttpServletResponse response, PrcProfitReportQuery query)
public AjaxResult exportOrders(PrcProfitReportQuery query)
{
List<PrcProfitReportOrderRow> rows = profitReportService.selectOrderRows(query);
new ExcelUtil<PrcProfitReportOrderRow>(PrcProfitReportOrderRow.class)
.exportExcel(response, rows, "订单毛利报表");
PrcProfitReportExport export = beginExport("ORDER", "订单维度毛利分析");
try
{
List<PrcProfitReportOrderRow> rows = profitReportService.selectOrderRows(query);
AjaxResult file = new ExcelUtil<PrcProfitReportOrderRow>(PrcProfitReportOrderRow.class)
.exportExcel(rows, "订单毛利报表");
return finishExport(export, rows.size(), file);
}
catch (RuntimeException e)
{
failExport(export, e);
throw e;
}
}
@Log(title = "毛利报表-产品维度", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('report:profit:export')")
@PostMapping("/products/export")
public void exportProducts(HttpServletResponse response, PrcProfitReportQuery query)
public AjaxResult exportProducts(PrcProfitReportQuery query)
{
List<PrcProfitReportProductRow> rows = profitReportService.selectProductRows(query);
new ExcelUtil<PrcProfitReportProductRow>(PrcProfitReportProductRow.class)
.exportExcel(response, rows, "产品毛利报表");
PrcProfitReportExport export = beginExport("PRODUCT", "产品维度毛利分析");
try
{
List<PrcProfitReportProductRow> rows = profitReportService.selectProductRows(query);
AjaxResult file = new ExcelUtil<PrcProfitReportProductRow>(PrcProfitReportProductRow.class)
.exportExcel(rows, "产品毛利报表");
return finishExport(export, rows.size(), file);
}
catch (RuntimeException e)
{
failExport(export, e);
throw e;
}
}
@PreAuthorize("@ss.hasPermi('report:profit:export')")
@GetMapping("/exports")
public TableDataInfo exports()
{
startPage();
return getDataTable(profitReportService.selectExports(getUsername()));
}
@PreAuthorize("@ss.hasPermi('report:profit:export')")
@GetMapping("/exports/{exportId}/download")
public void downloadExport(@PathVariable Long exportId, HttpServletResponse response) throws Exception
{
PrcProfitReportExport export = profitReportService.selectExport(exportId, getUsername());
if (export == null || !"SUCCESS".equals(export.getExportStatus())
|| export.getStorageKey() == null || !FileUtils.checkAllowDownload(export.getStorageKey()))
{
throw new ServiceException("导出文件不存在或尚未生成成功");
}
Path downloadRoot = Paths.get(BmsConfig.getDownloadPath()).toAbsolutePath().normalize();
Path filePath = downloadRoot.resolve(export.getStorageKey()).normalize();
if (!filePath.startsWith(downloadRoot) || !Files.isRegularFile(filePath))
{
throw new ServiceException("导出文件不存在或路径非法");
}
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
FileUtils.setAttachmentResponseHeader(response, export.getFileName());
FileUtils.writeBytes(filePath.toString(), response.getOutputStream());
}
private PrcProfitReportExport beginExport(String dimension, String filePrefix)
{
PrcProfitReportExport export = new PrcProfitReportExport();
export.setDimension(dimension);
export.setFileName(filePrefix + "_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".xlsx");
export.setExportStatus("PROCESSING");
export.setExportBy(getUsername());
if (profitReportService.createExport(export) != 1)
{
throw new ServiceException("创建导出日志失败");
}
return export;
}
private AjaxResult finishExport(PrcProfitReportExport export, int rowCount, AjaxResult file)
{
Object storageKey = file.get("msg");
if (storageKey == null || String.valueOf(storageKey).isBlank())
{
throw new ServiceException("导出文件生成失败");
}
export.setStorageKey(String.valueOf(storageKey));
export.setRowCount(rowCount);
export.setExportStatus("SUCCESS");
if (profitReportService.completeExport(export) != 1)
{
throw new ServiceException("保存导出日志失败");
}
return success(export);
}
private void failExport(PrcProfitReportExport export, RuntimeException e)
{
String message = e.getMessage();
if (message == null || message.isBlank())
{
message = "导出失败";
}
if (message.length() > 500)
{
message = message.substring(0, 500);
}
profitReportService.failExport(export.getExportId(), message);
}
}