diff --git a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/AiFeedBatchEntity.java b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/AiFeedBatchEntity.java index 75045486..b9a7230f 100644 --- a/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/AiFeedBatchEntity.java +++ b/pjcloud-canteen/pjcloud-canteen-api/src/main/java/com/bsd/pjcloud/canteen/entity/AiFeedBatchEntity.java @@ -25,6 +25,10 @@ public class AiFeedBatchEntity extends Model { private Long merchantId; + /** 列表回显用,非表字段 */ + @TableField(exist = false) + private String merchantName; + private String fileName; /** USER / RESERVE / TAKE_OUT */ diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/controller/AiFeedController.java b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/controller/AiFeedController.java index 56dd3fe5..a7afcf8d 100644 --- a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/controller/AiFeedController.java +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/controller/AiFeedController.java @@ -52,11 +52,13 @@ public class AiFeedController { return aiFeedImportService.getBatch(id); } - @Operation(summary = "批次导入明细(含跳过原因)") + @Operation(summary = "批次导入明细(分页,含跳过原因)") @GetMapping("/batch/{id}/items") @PreAuthorize("@pms.hasPermission('canteen_aiFeed_view')") - public R items(@PathVariable Long id) { - return aiFeedImportService.listItems(id); + public R items(@PathVariable Long id, + @RequestParam(required = false) String itemType, + Page page) { + return aiFeedImportService.pageItems(page, id, itemType); } @Operation(summary = "按批次清理演示数据") diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/AiFeedImportService.java b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/AiFeedImportService.java index 1bd4d663..cfc0e8d9 100644 --- a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/AiFeedImportService.java +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/AiFeedImportService.java @@ -20,6 +20,12 @@ public interface AiFeedImportService { /** 批次行明细(成功 USER/ORDER + 跳过 SKIP,含失败原因) */ R listItems(Long batchId); + /** + * 批次明细分页。 + * @param itemType ALL/SUCCESS/SKIP/USER/ORDER,空同 ALL + */ + R pageItems(Page page, Long batchId, String itemType); + R deleteBatch(Long batchId); /** 统一混合模板内容 */ diff --git a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/AiFeedImportServiceImpl.java b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/AiFeedImportServiceImpl.java index 5969acc5..7269ac1e 100644 --- a/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/AiFeedImportServiceImpl.java +++ b/pjcloud-canteen/pjcloud-canteen-biz/src/main/java/com/bsd/pjcloud/canteen/service/impl/AiFeedImportServiceImpl.java @@ -23,7 +23,9 @@ import com.bsd.pjcloud.hard.api.dto.order.remote.AiFeedOrderCreateDTO; import com.bsd.pjcloud.hard.api.feign.RemoteHardOrderService; import com.bsd.pjcloud.wallet.api.dto.AiFeedWalletEnsureDTO; import com.bsd.pjcloud.wallet.api.dto.AiFeedWalletEnsureResultDTO; +import com.bsd.pjcloud.wallet.api.feign.RemoteMchService; import com.bsd.pjcloud.wallet.api.feign.RemoteWalletService; +import com.bsd.pjcloud.wallet.api.vo.MchManageVo; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; @@ -40,7 +42,6 @@ import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -93,6 +94,7 @@ public class AiFeedImportServiceImpl implements AiFeedImportService { private final RemoteUserService remoteUserService; private final RemoteWalletService remoteWalletService; private final RemoteHardOrderService remoteHardOrderService; + private final RemoteMchService remoteMchService; private final ObjectMapper objectMapper; @Override @@ -640,10 +642,13 @@ public class AiFeedImportServiceImpl implements AiFeedImportService { item.setBatchId(batchId); item.setItemType(ITEM_ORDER); item.setRefId(orderId); - item.setBizKey("AIFEED-" + or.dto().getBatchNo() + "-" + or.dto().getSeq()); + // 列表「手机号」列读 bizKey;订单号放 extra_json.orderNo + item.setBizKey(or.phone()); + String orderNo = "AIFEED-" + or.dto().getBatchNo() + "-" + or.dto().getSeq(); item.setExtraJson(JSONUtil.createObj() .set("lineNo", or.lineNo()) .set("phone", or.phone()) + .set("orderNo", orderNo) .set("rowType", or.rowType()) .set("walletId", walletId) .set("status", "SUCCESS") @@ -703,9 +708,45 @@ public class AiFeedImportServiceImpl implements AiFeedImportService { Page result = batchMapper.selectPage(page, Wrappers.lambdaQuery() .eq(StrUtil.isNotBlank(status), AiFeedBatchEntity::getStatus, status) .orderByDesc(AiFeedBatchEntity::getCreateTime)); + fillMerchantNames(result.getRecords()); return R.ok(result); } + /** 列表回填商户名称 */ + private void fillMerchantNames(List records) { + if (records == null || records.isEmpty()) { + return; + } + List mchIds = records.stream() + .map(AiFeedBatchEntity::getMerchantId) + .filter(Objects::nonNull) + .distinct() + .toList(); + if (mchIds.isEmpty()) { + return; + } + Map nameById = new HashMap<>(); + try { + R> mchR = remoteMchService.getByIds(mchIds); + if (mchR != null && mchR.isOk() && mchR.getData() != null) { + for (MchManageVo mch : mchR.getData()) { + if (mch != null && mch.getId() != null) { + nameById.put(mch.getId(), mch.getName()); + } + } + } + } + catch (Exception ex) { + log.warn("AI喂数批次回填商户名失败: {}", ex.getMessage()); + } + for (AiFeedBatchEntity row : records) { + if (row.getMerchantId() == null) { + continue; + } + row.setMerchantName(nameById.getOrDefault(row.getMerchantId(), String.valueOf(row.getMerchantId()))); + } + } + @Override public R getBatch(Long batchId) { AiFeedBatchEntity batch = batchMapper.selectById(batchId); @@ -717,36 +758,35 @@ public class AiFeedImportServiceImpl implements AiFeedImportService { @Override public R listItems(Long batchId) { + Page page = new Page<>(1, 5000); + return pageItems(page, batchId, null); + } + + @Override + public R pageItems(Page page, Long batchId, String itemType) { AiFeedBatchEntity batch = batchMapper.selectById(batchId); if (batch == null) { return R.failed("批次不存在"); } - List items = itemMapper.selectList(Wrappers.lambdaQuery() - .eq(AiFeedBatchItemEntity::getBatchId, batchId) - .orderByAsc(AiFeedBatchItemEntity::getId)); - items.sort(Comparator.comparingInt(this::resolveLineNo)); - return R.ok(items); - } - - private int resolveLineNo(AiFeedBatchItemEntity item) { - if (item == null) { - return 0; + String type = StrUtil.blankToDefault(itemType, "ALL").trim().toUpperCase(Locale.ROOT); + var qw = Wrappers.lambdaQuery() + .eq(AiFeedBatchItemEntity::getBatchId, batchId); + if ("SUCCESS".equals(type)) { + qw.in(AiFeedBatchItemEntity::getItemType, ITEM_USER, ITEM_ORDER); } - try { - if (StrUtil.isNotBlank(item.getExtraJson())) { - Integer lineNo = JSONUtil.parseObj(item.getExtraJson()).getInt("lineNo"); - if (lineNo != null && lineNo > 0) { - return lineNo; - } - } + else if ("SKIP".equals(type)) { + qw.eq(AiFeedBatchItemEntity::getItemType, ITEM_SKIP); } - catch (Exception ignored) { - // ignore + else if ("USER".equals(type)) { + qw.eq(AiFeedBatchItemEntity::getItemType, ITEM_USER); } - if (ITEM_SKIP.equals(item.getItemType()) && item.getRefId() != null) { - return item.getRefId().intValue(); + else if ("ORDER".equals(type)) { + qw.eq(AiFeedBatchItemEntity::getItemType, ITEM_ORDER); } - return 0; + // 按主键顺序近似导入顺序;行号在 extra_json,分页场景不内存全量排序 + qw.orderByAsc(AiFeedBatchItemEntity::getId); + Page result = itemMapper.selectPage(page, qw); + return R.ok(result); } @Override