1
This commit is contained in:
@@ -11,6 +11,8 @@ public interface IGroupRebateExcelUploadService {
|
||||
*/
|
||||
void saveRecordInNewTransaction(GroupRebateExcelUpload row);
|
||||
|
||||
void updateRecordInNewTransaction(GroupRebateExcelUpload row);
|
||||
|
||||
GroupRebateExcelUpload selectGroupRebateExcelUploadById(Long id);
|
||||
|
||||
List<GroupRebateExcelUpload> selectGroupRebateExcelUploadList(GroupRebateExcelUpload query);
|
||||
|
||||
@@ -7,9 +7,11 @@ import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.jarvis.domain.GroupRebateExcelUpload;
|
||||
import com.ruoyi.jarvis.domain.JDOrder;
|
||||
import com.ruoyi.jarvis.domain.dto.RebateRemarkItem;
|
||||
import com.ruoyi.jarvis.mapper.GroupRebateExcelUploadMapper;
|
||||
import com.ruoyi.jarvis.mapper.JDOrderMapper;
|
||||
import com.ruoyi.jarvis.service.IGroupRebateExcelUploadService;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
@@ -38,6 +40,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -62,6 +65,9 @@ public class GroupRebateExcelImportService {
|
||||
@Resource
|
||||
private JDOrderMapper jdOrderMapper;
|
||||
|
||||
@Resource
|
||||
private GroupRebateExcelUploadMapper groupRebateExcelUploadMapper;
|
||||
|
||||
@Resource
|
||||
private IGroupRebateExcelUploadService groupRebateExcelUploadService;
|
||||
|
||||
@@ -104,9 +110,10 @@ public class GroupRebateExcelImportService {
|
||||
}
|
||||
|
||||
File diskFile = resolveDiskFile(webPath);
|
||||
Long recordId = insertInitialUploadRecord(originalFilename, webPath, fileSize, title);
|
||||
Map<String, Object> result;
|
||||
try {
|
||||
result = self.processWorkbookTransactional(diskFile, title);
|
||||
result = self.processWorkbookTransactional(diskFile, title, recordId);
|
||||
} catch (Exception e) {
|
||||
log.error("后返表导入处理异常", e);
|
||||
result = new HashMap<>();
|
||||
@@ -115,13 +122,136 @@ public class GroupRebateExcelImportService {
|
||||
result.put("documentTitle", title);
|
||||
}
|
||||
result.put("savedFilePath", webPath);
|
||||
Long recordId = persistUploadRecord(originalFilename, webPath, fileSize, title, result);
|
||||
finalizeUploadRecord(recordId, originalFilename, webPath, fileSize, title, result);
|
||||
result.put("uploadRecordId", recordId);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量导入:按顺序逐个调用 {@link #importExcel},在同一请求内由后台依次处理完成。
|
||||
*
|
||||
* @param documentTitle 仅当恰好 1 个有效文件时作为文档标题;多文件时忽略,各文件用各自文件名。
|
||||
*/
|
||||
public Map<String, Object> importExcelBatch(MultipartFile[] files, String documentTitle) {
|
||||
if (files == null || files.length == 0) {
|
||||
Map<String, Object> empty = new HashMap<>();
|
||||
empty.put("success", false);
|
||||
empty.put("message", "请选择文件");
|
||||
return empty;
|
||||
}
|
||||
List<MultipartFile> list = new ArrayList<>();
|
||||
for (MultipartFile f : files) {
|
||||
if (f != null && !f.isEmpty()) {
|
||||
list.add(f);
|
||||
}
|
||||
}
|
||||
if (list.isEmpty()) {
|
||||
Map<String, Object> empty = new HashMap<>();
|
||||
empty.put("success", false);
|
||||
empty.put("message", "没有有效文件");
|
||||
return empty;
|
||||
}
|
||||
boolean single = list.size() == 1;
|
||||
String sharedTitle = (single && StringUtils.isNotEmpty(documentTitle)) ? documentTitle.trim() : null;
|
||||
|
||||
int ok = 0;
|
||||
int fail = 0;
|
||||
List<Map<String, Object>> failures = new ArrayList<>();
|
||||
for (MultipartFile file : list) {
|
||||
try {
|
||||
Map<String, Object> r = importExcel(file, sharedTitle);
|
||||
if (Boolean.TRUE.equals(r.get("success"))) {
|
||||
ok++;
|
||||
} else {
|
||||
fail++;
|
||||
addBatchFailureBrief(failures, file.getOriginalFilename(), r.get("message"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("批量后返表:单文件导入失败 {}", file.getOriginalFilename(), e);
|
||||
fail++;
|
||||
addBatchFailureBrief(failures, file.getOriginalFilename(), e.getMessage());
|
||||
}
|
||||
}
|
||||
Map<String, Object> out = new HashMap<>();
|
||||
out.put("success", true);
|
||||
out.put("totalFiles", list.size());
|
||||
out.put("successCount", ok);
|
||||
out.put("failCount", fail);
|
||||
out.put("message", String.format(Locale.ROOT,
|
||||
"已处理 %d 个文件:成功 %d,失败 %d。明细可在「后返上传记录」查看。",
|
||||
list.size(), ok, fail));
|
||||
if (!failures.isEmpty()) {
|
||||
out.put("failures", failures);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private static void addBatchFailureBrief(List<Map<String, Object>> failures, String filename, Object message) {
|
||||
if (failures.size() >= 15) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> fb = new HashMap<>(2);
|
||||
fb.put("filename", filename);
|
||||
fb.put("message", message != null ? message.toString() : "");
|
||||
failures.add(fb);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一条上传记录:从订单 rebate_remark_json 中移除本次导入写入的条目,并删除数据库记录与磁盘文件。
|
||||
*/
|
||||
public Map<String, Object> deleteUploadRecord(Long id) {
|
||||
if (id == null) {
|
||||
throw new ServiceException("记录 ID 无效");
|
||||
}
|
||||
GroupRebateExcelUpload rec = groupRebateExcelUploadService.selectGroupRebateExcelUploadById(id);
|
||||
if (rec == null) {
|
||||
throw new ServiceException("上传记录不存在");
|
||||
}
|
||||
String filePath = rec.getFilePath();
|
||||
Map<String, Object> data = self.deleteUploadRecordTransactional(id, rec);
|
||||
deleteUploadDiskFileIfPresent(filePath);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, Object> processWorkbookTransactional(File diskFile, String title) throws Exception {
|
||||
public Map<String, Object> deleteUploadRecordTransactional(Long id, GroupRebateExcelUpload rec) {
|
||||
Set<Long> orderIds = new LinkedHashSet<>();
|
||||
List<Long> fromDetail = parseAffectedOrderIds(rec.getResultDetailJson());
|
||||
if (fromDetail != null) {
|
||||
orderIds.addAll(fromDetail);
|
||||
}
|
||||
if (orderIds.isEmpty()) {
|
||||
List<Long> fromJson = jdOrderMapper.selectOrderIdsByRebateRemarkUploadRecordId(id);
|
||||
if (fromJson != null) {
|
||||
orderIds.addAll(fromJson);
|
||||
}
|
||||
}
|
||||
int ordersUpdated = 0;
|
||||
for (Long oid : orderIds) {
|
||||
if (stripRebateRemarkItemsByUploadRecordId(oid, id)) {
|
||||
ordersUpdated++;
|
||||
}
|
||||
}
|
||||
int deleted = groupRebateExcelUploadMapper.deleteGroupRebateExcelUploadById(id);
|
||||
if (deleted == 0) {
|
||||
throw new ServiceException("删除上传记录失败");
|
||||
}
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("ordersScanned", orderIds.size());
|
||||
data.put("ordersRemarkUpdated", ordersUpdated);
|
||||
data.put("revertedByUploadRecordId", id);
|
||||
if (orderIds.isEmpty()) {
|
||||
data.put("message", "已删除上传记录;未找到可回滚的订单后返备注(多为本功能上线前的历史导入,请按需手工改订单)");
|
||||
} else {
|
||||
data.put("message", String.format(Locale.ROOT,
|
||||
"已删除上传记录;已扫描 %d 个订单,从 %d 个订单移除了本次导入对应的后返备注",
|
||||
orderIds.size(), ordersUpdated));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, Object> processWorkbookTransactional(File diskFile, String title, Long uploadRecordId) throws Exception {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try (InputStream is = new FileInputStream(diskFile); Workbook wb = WorkbookFactory.create(is)) {
|
||||
Sheet sheet = wb.getNumberOfSheets() > 0 ? wb.getSheetAt(0) : null;
|
||||
@@ -155,8 +285,40 @@ public class GroupRebateExcelImportService {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (hm.whetherRebateCol >= 0) {
|
||||
int orderDataRows = 0;
|
||||
boolean anyWhetherFilled = false;
|
||||
for (int r = headerRowIndex + 1; r <= sheet.getLastRowNum(); r++) {
|
||||
Row scanRow = sheet.getRow(r);
|
||||
if (scanRow == null) {
|
||||
continue;
|
||||
}
|
||||
String orderNoScan = normalizeOrderNo(getCellText(scanRow, hm.orderCol));
|
||||
if (orderNoScan.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
orderDataRows++;
|
||||
String w = trimToNull(getCellText(scanRow, hm.whetherRebateCol));
|
||||
if (w != null) {
|
||||
anyWhetherFilled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (orderDataRows > 0 && !anyWhetherFilled) {
|
||||
result.put("success", false);
|
||||
result.put("message", "「是否返现」列全部为空,未写入任何订单,请补全该列后重新上传。");
|
||||
result.put("documentTitle", title);
|
||||
result.put("dataRows", orderDataRows);
|
||||
result.put("updatedOrders", 0);
|
||||
result.put("notFoundOrderNos", new ArrayList<>());
|
||||
result.put("errors", new ArrayList<>());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
int dataRows = 0;
|
||||
int updatedOrders = 0;
|
||||
Set<Long> affectedOrderIds = new LinkedHashSet<>();
|
||||
Set<String> notFound = new LinkedHashSet<>();
|
||||
List<String> errors = new ArrayList<>();
|
||||
|
||||
@@ -194,7 +356,8 @@ public class GroupRebateExcelImportService {
|
||||
}
|
||||
|
||||
try {
|
||||
appendRebateRemark(order, title, whether, amountStr);
|
||||
appendRebateRemark(order, title, whether, amountStr, uploadRecordId);
|
||||
affectedOrderIds.add(order.getId());
|
||||
updatedOrders++;
|
||||
} catch (Exception e) {
|
||||
log.warn("写入后返备注失败 orderNo={} id={}", orderNo, order.getId(), e);
|
||||
@@ -208,6 +371,7 @@ public class GroupRebateExcelImportService {
|
||||
result.put("updatedOrders", updatedOrders);
|
||||
result.put("notFoundOrderNos", new ArrayList<>(notFound));
|
||||
result.put("errors", errors);
|
||||
result.put("affectedOrderIds", new ArrayList<>(affectedOrderIds));
|
||||
result.put("message", String.format(Locale.ROOT,
|
||||
"解析完成:有效数据行 %d,匹配并更新订单 %d,未找到订单 %d 条",
|
||||
dataRows, updatedOrders, notFound.size()));
|
||||
@@ -215,18 +379,46 @@ public class GroupRebateExcelImportService {
|
||||
}
|
||||
}
|
||||
|
||||
private Long persistUploadRecord(String originalFilename, String webPath, long fileSize,
|
||||
String title, Map<String, Object> procResult) {
|
||||
private Long insertInitialUploadRecord(String originalFilename, String webPath, long fileSize, String title) {
|
||||
GroupRebateExcelUpload row = new GroupRebateExcelUpload();
|
||||
row.setOriginalFilename(originalFilename);
|
||||
row.setFilePath(StringUtils.isNotEmpty(webPath) ? webPath : "");
|
||||
row.setFilePath(webPath);
|
||||
row.setFileSize(fileSize);
|
||||
row.setDocumentTitle(title);
|
||||
row.setImportStatus(1);
|
||||
row.setDataRows(0);
|
||||
row.setUpdatedOrders(0);
|
||||
row.setNotFoundCount(0);
|
||||
JSONObject d = new JSONObject();
|
||||
d.put("message", "解析中");
|
||||
d.put("documentTitle", title);
|
||||
row.setResultDetailJson(d.toJSONString());
|
||||
try {
|
||||
row.setCreateBy(SecurityUtils.getUsername());
|
||||
} catch (Exception e) {
|
||||
row.setCreateBy("");
|
||||
}
|
||||
groupRebateExcelUploadService.saveRecordInNewTransaction(row);
|
||||
return row.getId();
|
||||
}
|
||||
|
||||
private void finalizeUploadRecord(Long recordId, String originalFilename, String webPath, long fileSize,
|
||||
String title, Map<String, Object> procResult) {
|
||||
GroupRebateExcelUpload row = new GroupRebateExcelUpload();
|
||||
row.setId(recordId);
|
||||
row.setOriginalFilename(originalFilename);
|
||||
row.setFilePath(StringUtils.isNotEmpty(webPath) ? webPath : "");
|
||||
row.setFileSize(fileSize);
|
||||
row.setDocumentTitle(title);
|
||||
applyProcResultToRow(row, procResult);
|
||||
try {
|
||||
groupRebateExcelUploadService.updateRecordInNewTransaction(row);
|
||||
} catch (Exception e) {
|
||||
log.error("更新后返上传记录失败 id={}", recordId, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyProcResultToRow(GroupRebateExcelUpload row, Map<String, Object> procResult) {
|
||||
boolean ok = Boolean.TRUE.equals(procResult.get("success"));
|
||||
row.setImportStatus(ok ? 2 : 1);
|
||||
row.setDataRows(asInt(procResult.get("dataRows")));
|
||||
@@ -247,7 +439,25 @@ public class GroupRebateExcelImportService {
|
||||
if (procResult.containsKey("savedFilePath")) {
|
||||
detail.put("savedFilePath", procResult.get("savedFilePath"));
|
||||
}
|
||||
if (procResult.containsKey("affectedOrderIds")) {
|
||||
detail.put("affectedOrderIds", procResult.get("affectedOrderIds"));
|
||||
}
|
||||
row.setResultDetailJson(detail.toJSONString());
|
||||
}
|
||||
|
||||
private Long persistUploadRecord(String originalFilename, String webPath, long fileSize,
|
||||
String title, Map<String, Object> procResult) {
|
||||
GroupRebateExcelUpload row = new GroupRebateExcelUpload();
|
||||
row.setOriginalFilename(originalFilename);
|
||||
row.setFilePath(StringUtils.isNotEmpty(webPath) ? webPath : "");
|
||||
row.setFileSize(fileSize);
|
||||
row.setDocumentTitle(title);
|
||||
try {
|
||||
row.setCreateBy(SecurityUtils.getUsername());
|
||||
} catch (Exception e) {
|
||||
row.setCreateBy("");
|
||||
}
|
||||
applyProcResultToRow(row, procResult);
|
||||
|
||||
try {
|
||||
groupRebateExcelUploadService.saveRecordInNewTransaction(row);
|
||||
@@ -258,6 +468,69 @@ public class GroupRebateExcelImportService {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Long> parseAffectedOrderIds(String resultDetailJson) {
|
||||
if (StringUtils.isEmpty(resultDetailJson)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
JSONObject o = JSON.parseObject(resultDetailJson);
|
||||
if (o == null || !o.containsKey("affectedOrderIds")) {
|
||||
return null;
|
||||
}
|
||||
return o.getList("affectedOrderIds", Long.class);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean stripRebateRemarkItemsByUploadRecordId(Long orderId, Long uploadRecordId) {
|
||||
JDOrder order = jdOrderMapper.selectJDOrderById(orderId);
|
||||
if (order == null) {
|
||||
return false;
|
||||
}
|
||||
List<RebateRemarkItem> list = new ArrayList<>();
|
||||
String existing = order.getRebateRemarkJson();
|
||||
if (existing != null && !existing.trim().isEmpty()) {
|
||||
try {
|
||||
list.addAll(JSON.parseArray(existing, RebateRemarkItem.class));
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int before = list.size();
|
||||
list.removeIf(it -> Objects.equals(uploadRecordId, it.getUploadRecordId()));
|
||||
if (list.size() == before) {
|
||||
return false;
|
||||
}
|
||||
boolean hasAbnormal = false;
|
||||
for (RebateRemarkItem it : list) {
|
||||
if (Boolean.TRUE.equals(it.getAbnormal())) {
|
||||
hasAbnormal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
JDOrder upd = new JDOrder();
|
||||
upd.setId(order.getId());
|
||||
upd.setRebateRemarkJson(list.isEmpty() ? "[]" : JSON.toJSONString(list));
|
||||
upd.setRebateRemarkHasAbnormal(hasAbnormal ? 1 : 0);
|
||||
jdOrderMapper.updateJDOrder(upd);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void deleteUploadDiskFileIfPresent(String webPath) {
|
||||
if (StringUtils.isEmpty(webPath)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
File f = resolveDiskFile(webPath);
|
||||
if (f.isFile() && !f.delete()) {
|
||||
log.warn("删除后返上传文件失败: {}", f.getAbsolutePath());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("删除后返上传文件异常 path={}", webPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Integer asInt(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
@@ -299,7 +572,8 @@ public class GroupRebateExcelImportService {
|
||||
return new File(RuoYiConfig.getProfile(), sub);
|
||||
}
|
||||
|
||||
private void appendRebateRemark(JDOrder order, String documentTitle, String whetherRebate, String rebateAmount) {
|
||||
private void appendRebateRemark(JDOrder order, String documentTitle, String whetherRebate, String rebateAmount,
|
||||
Long uploadRecordId) {
|
||||
List<RebateRemarkItem> list = new ArrayList<>();
|
||||
String existing = order.getRebateRemarkJson();
|
||||
if (existing != null && !existing.trim().isEmpty()) {
|
||||
@@ -317,6 +591,7 @@ public class GroupRebateExcelImportService {
|
||||
item.setRebateAmount(rebateAmount);
|
||||
item.setUploadTime(System.currentTimeMillis());
|
||||
item.setAbnormal(isAbnormalWhetherRebate(whetherRebate));
|
||||
item.setUploadRecordId(uploadRecordId);
|
||||
list.add(item);
|
||||
|
||||
boolean hasAbnormal = false;
|
||||
|
||||
@@ -22,6 +22,12 @@ public class GroupRebateExcelUploadServiceImpl implements IGroupRebateExcelUploa
|
||||
groupRebateExcelUploadMapper.insertGroupRebateExcelUpload(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
|
||||
public void updateRecordInNewTransaction(GroupRebateExcelUpload row) {
|
||||
groupRebateExcelUploadMapper.updateGroupRebateExcelUpload(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupRebateExcelUpload selectGroupRebateExcelUploadById(Long id) {
|
||||
return groupRebateExcelUploadMapper.selectGroupRebateExcelUploadById(id);
|
||||
|
||||
Reference in New Issue
Block a user