package com.vincent.rsf.server.common.service;
|
|
import com.vincent.rsf.framework.exception.CoolException;
|
import com.vincent.rsf.server.common.domain.BaseParam;
|
import com.vincent.rsf.server.common.utils.ExcelUtil;
|
import org.springframework.stereotype.Service;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Objects;
|
import java.util.Set;
|
import java.util.function.Function;
|
|
@Service
|
public class ListExportService {
|
private static final Set<String> EXPORT_ONLY_KEYS = Set.of(
|
"columns",
|
"reportTitle",
|
"reportDate",
|
"printedAt",
|
"operator",
|
"count",
|
"report_title",
|
"report_date",
|
"printed_at"
|
);
|
|
public <T, P extends BaseParam> void export(
|
Map<String, Object> map,
|
Function<Map<String, Object>, P> paramBuilder,
|
ListExportHandler<T, P> exportHandler,
|
HttpServletResponse response
|
) throws Exception {
|
Map<String, Object> sanitizedMap = sanitizeExportMap(map);
|
P baseParam = paramBuilder.apply(sanitizedMap);
|
List<ExcelUtil.ExportColumn> columns = buildExportColumns(map);
|
if (columns.isEmpty()) {
|
throw new CoolException("导出列不能为空");
|
}
|
|
List<T> records = getExportRecords(sanitizedMap, baseParam, exportHandler);
|
exportHandler.fillExportFields(records);
|
|
List<Map<String, Object>> rows = records.stream()
|
.map(record -> exportHandler.toExportRow(record, columns))
|
.toList();
|
|
ExcelUtil.ExportMeta exportMeta = buildExportMeta(map, rows.size(), exportHandler.defaultReportTitle());
|
ExcelUtil.build(ExcelUtil.create(rows, columns, exportMeta), response);
|
}
|
|
private Map<String, Object> sanitizeExportMap(Map<String, Object> map) {
|
Map<String, Object> exportMap = new HashMap<>(map);
|
EXPORT_ONLY_KEYS.forEach(exportMap::remove);
|
exportMap.remove("meta");
|
|
sanitizeNestedMap(exportMap, "filter");
|
sanitizeNestedMap(exportMap, "filterValues");
|
return exportMap;
|
}
|
|
private void sanitizeNestedMap(Map<String, Object> exportMap, String key) {
|
Object nestedObject = exportMap.get(key);
|
if (nestedObject instanceof Map<?, ?> nestedMap) {
|
Map<String, Object> sanitizedMap = new HashMap<>();
|
for (Map.Entry<?, ?> entry : nestedMap.entrySet()) {
|
String nestedKey = String.valueOf(entry.getKey());
|
if (!EXPORT_ONLY_KEYS.contains(nestedKey)) {
|
sanitizedMap.put(nestedKey, entry.getValue());
|
}
|
}
|
exportMap.put(key, sanitizedMap);
|
}
|
}
|
|
private List<ExcelUtil.ExportColumn> buildExportColumns(Map<String, Object> map) {
|
Object columnsObject = map.get("columns");
|
if (Objects.isNull(columnsObject)) {
|
Object metaObject = map.get("meta");
|
if (metaObject instanceof Map<?, ?> metaMap) {
|
columnsObject = metaMap.get("columns");
|
}
|
}
|
|
if (!(columnsObject instanceof List<?> rawColumns)) {
|
return Collections.emptyList();
|
}
|
|
List<ExcelUtil.ExportColumn> columns = new ArrayList<>();
|
for (Object rawColumn : rawColumns) {
|
if (!(rawColumn instanceof Map<?, ?> columnMap)) {
|
continue;
|
}
|
Object source = columnMap.get("source");
|
Object label = columnMap.get("label");
|
if (Objects.isNull(source) || Objects.isNull(label)) {
|
continue;
|
}
|
columns.add(new ExcelUtil.ExportColumn(String.valueOf(source), String.valueOf(label)));
|
}
|
return columns;
|
}
|
|
private <T, P extends BaseParam> List<T> getExportRecords(
|
Map<String, Object> sanitizedMap,
|
P baseParam,
|
ListExportHandler<T, P> exportHandler
|
) {
|
List<Long> ids = parseExportIds(sanitizedMap.get("ids"));
|
if (!ids.isEmpty()) {
|
return exportHandler.listByIds(ids);
|
}
|
return exportHandler.listByFilter(sanitizedMap, baseParam);
|
}
|
|
private List<Long> parseExportIds(Object idsObject) {
|
if (idsObject instanceof List<?> ids && !ids.isEmpty()) {
|
return ids.stream()
|
.map(String::valueOf)
|
.map(Long::valueOf)
|
.toList();
|
}
|
if (idsObject instanceof Object[] ids && ids.length > 0) {
|
List<Long> exportIds = new ArrayList<>();
|
for (Object id : ids) {
|
exportIds.add(Long.valueOf(String.valueOf(id)));
|
}
|
return exportIds;
|
}
|
return Collections.emptyList();
|
}
|
|
private ExcelUtil.ExportMeta buildExportMeta(Map<String, Object> map, int count, String defaultReportTitle) {
|
Object metaObject = map.get("meta");
|
if (!(metaObject instanceof Map<?, ?> metaMap)) {
|
return new ExcelUtil.ExportMeta(defaultReportTitle, "", "", "", count);
|
}
|
|
String reportTitle = getMetaValue(metaMap, "reportTitle", defaultReportTitle);
|
String reportDate = getMetaValue(metaMap, "reportDate", "");
|
String printedAt = getMetaValue(metaMap, "printedAt", "");
|
String operator = getMetaValue(metaMap, "operator", "");
|
return new ExcelUtil.ExportMeta(reportTitle, reportDate, printedAt, operator, count);
|
}
|
|
private String getMetaValue(Map<?, ?> metaMap, String key, String defaultValue) {
|
Object value = metaMap.get(key);
|
return Objects.isNull(value) ? defaultValue : String.valueOf(value);
|
}
|
}
|