This commit is contained in:
van
2026-06-03 12:06:43 +08:00
parent 6412168cc6
commit 67e6723685
12 changed files with 278 additions and 29 deletions

View File

@@ -32,6 +32,7 @@ import com.ruoyi.jarvis.domain.dto.JDOrderSimpleDTO;
import com.ruoyi.jarvis.domain.dto.QuickRecordModelOption;
import com.ruoyi.jarvis.domain.dto.QuickRecordModelShopOption;
import com.ruoyi.jarvis.util.QuickRecordModelShopOptionUtil;
import com.ruoyi.jarvis.service.IJDOrderModelShopService;
import com.ruoyi.jarvis.service.IJDOrderProfitService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.jarvis.service.IJDOrderService;
@@ -58,6 +59,7 @@ public class JDOrderListController extends BaseController
private final ObjectMapper objectMapper;
private final ISysConfigService sysConfigService;
private final IJDOrderModelShopService jdOrderModelShopService;
public JDOrderListController(IJDOrderService jdOrderService, IJDOrderProfitService jdOrderProfitService,
IOrderRowsService orderRowsService,
@@ -65,7 +67,8 @@ public class JDOrderListController extends BaseController
GroupRebateExcelImportService groupRebateExcelImportService,
IGroupRebateExcelUploadService groupRebateExcelUploadService,
ObjectMapper objectMapper,
ISysConfigService sysConfigService) {
ISysConfigService sysConfigService,
IJDOrderModelShopService jdOrderModelShopService) {
this.jdOrderService = jdOrderService;
this.jdOrderProfitService = jdOrderProfitService;
this.orderRowsService = orderRowsService;
@@ -74,6 +77,7 @@ public class JDOrderListController extends BaseController
this.groupRebateExcelUploadService = groupRebateExcelUploadService;
this.objectMapper = objectMapper;
this.sysConfigService = sysConfigService;
this.jdOrderModelShopService = jdOrderModelShopService;
}
/**
@@ -196,6 +200,16 @@ public class JDOrderListController extends BaseController
return AjaxResult.success(options);
}
/**
* 一键迁移:将 model_number 末尾匹配的店铺前缀写入 model_shop并从 model_number 截掉。
* 需先配置 quickRecord.modelShopOptions。
*/
@Log(title = "JD订单型号店铺拆分迁移", businessType = BusinessType.UPDATE)
@PostMapping("/migrateModelShop")
public AjaxResult migrateModelShop() {
return AjaxResult.success(jdOrderService.migrateModelShopSplit());
}
/**
* 导入跟团返现类 Excel按「单号/订单号」匹配系统订单,将「是否返现」「总共返现」等写入后返备注(可多次导入累加);文件落盘并记上传记录。
*/
@@ -331,6 +345,7 @@ public class JDOrderListController extends BaseController
public AjaxResult edit(@RequestBody JsonNode root) throws JsonProcessingException {
JDOrder jdOrder = objectMapper.treeToValue(root, JDOrder.class);
applyExtraCostFromPayload(root, jdOrder);
jdOrderModelShopService.normalizeOrder(jdOrder);
jdOrderProfitService.recalculate(jdOrder);
jdOrder.getParams().put("applyProfitFields", Boolean.TRUE);
int rows = jdOrderService.updateJDOrder(jdOrder);
@@ -642,8 +657,8 @@ public class JDOrderListController extends BaseController
String duoduoOrderNo = o.getThirdPartyOrderNo() != null && !o.getThirdPartyOrderNo().trim().isEmpty()
? o.getThirdPartyOrderNo() : (o.getRemark() != null ? o.getRemark() : "");
// 型号
String modelNumber = o.getModelNumber() != null ? o.getModelNumber() : "";
// 型号(对外完整型号 = 本体 + 店铺前缀)
String modelNumber = QuickRecordModelShopOptionUtil.fullModelNumber(o);
// 数量固定为1
String quantity = "1";

View File

@@ -27,10 +27,14 @@ public class JDOrder extends BaseEntity {
@Excel(name = "分销标记")
private String distributionMark;
/** 型号 */
/** 型号(本体,不含店铺后缀) */
@Excel(name = "型号")
private String modelNumber;
/** 型号店铺短前缀(如海尔厨房;完整型号 = modelNumber + modelShop */
@Excel(name = "型号店铺")
private String modelShop;
/** 列表筛选:型号不含这些子串(逗号/空格分隔,对应 SQL 多条 NOT LIKE不入库 */
@Transient
private String modelNumberExclude;

View File

@@ -10,6 +10,9 @@ public class QuickRecordModelOption {
private String modelNumber;
/** 型号店铺短前缀 */
private String modelShop;
/** 最近一次订单的下单付款金额 */
private Double lastPaymentAmount;

View File

@@ -67,6 +67,13 @@ public interface JDOrderMapper {
* 每个型号取其主键最大的一条订单的付款 / 后返(用于快捷录单下拉回填)
*/
List<QuickRecordModelOption> selectQuickRecordModelOptions();
/** 待拆分型号店铺的历史订单(全表扫描,由业务层按配置过滤) */
List<JDOrder> selectOrdersPendingModelShopMigration();
int updateModelShopFields(@org.apache.ibatis.annotations.Param("id") Long id,
@org.apache.ibatis.annotations.Param("modelNumber") String modelNumber,
@org.apache.ibatis.annotations.Param("modelShop") String modelShop);
}

View File

@@ -0,0 +1,25 @@
package com.ruoyi.jarvis.service;
import java.util.Map;
import com.ruoyi.jarvis.domain.JDOrder;
import com.ruoyi.jarvis.domain.dto.QuickRecordModelShopOption;
import java.util.List;
/**
* 型号与店铺前缀拆分、归一化及历史数据迁移。
*/
public interface IJDOrderModelShopService {
List<QuickRecordModelShopOption> loadShopOptions();
void normalizeOrder(JDOrder order);
String fullModel(JDOrder order);
String lookupModelBase(String rawModel);
/** 一键迁移:将 model_number 末尾匹配的店铺前缀写入 model_shop 并从 model_number 截掉 */
Map<String, Object> migrateExistingOrders();
}

View File

@@ -52,6 +52,9 @@ public interface IJDOrderService {
/** 快捷录单:型号及最近一次单的付款 / 后返 */
List<QuickRecordModelOption> selectQuickRecordModelOptions();
/** 一键迁移:拆分 model_number 末尾店铺前缀到 model_shop */
java.util.Map<String, Object> migrateModelShopSplit();
}

View File

@@ -7,6 +7,7 @@ import com.ruoyi.jarvis.domain.WeComShareLinkLogisticsJob;
import com.ruoyi.jarvis.service.IInstructionService;
import com.ruoyi.jarvis.service.IOrderRowsService;
import com.ruoyi.jarvis.service.IJDOrderService;
import com.ruoyi.jarvis.service.IJDOrderModelShopService;
import com.ruoyi.jarvis.service.IProductJdConfigService;
import com.ruoyi.jarvis.service.IPhoneReplaceConfigService;
import com.ruoyi.jarvis.service.SuperAdminService;
@@ -42,6 +43,8 @@ public class InstructionServiceImpl implements IInstructionService {
@Resource
private IJDOrderService jdOrderService;
@Resource
private IJDOrderModelShopService jdOrderModelShopService;
@Resource
private SuperAdminService superAdminService;
@Resource
private StringRedisTemplate stringRedisTemplate;
@@ -358,13 +361,13 @@ public class InstructionServiceImpl implements IInstructionService {
// 统一截取分销标记
list.forEach(order -> order.setDistributionMark(truncateDistributionMark(order.getDistributionMark())));
String low = kw.toLowerCase(Locale.ROOT);
List<JDOrder> matched = list.stream().filter(o -> contains(o.getRemark(), low) || contains(o.getOrderId(), low) || contains(o.getModelNumber(), low) || contains(o.getAddress(), low) || contains(o.getBuyer(), low)).limit(50).collect(Collectors.toList());
List<JDOrder> matched = list.stream().filter(o -> contains(o.getRemark(), low) || contains(o.getOrderId(), low) || contains(o.getModelNumber(), low) || contains(o.getModelShop(), low) || contains(orderFullModel(o), low) || contains(o.getAddress(), low) || contains(o.getBuyer(), low)).limit(50).collect(Collectors.toList());
if (matched.isEmpty()) return Collections.singletonList("未找到匹配的订单");
StringBuilder sb = new StringBuilder();
int i = 0;
for (JDOrder o : matched) {
i++;
sb.append(i).append(", 单:").append(nvl(o.getRemark())).append("\n分销标记").append(nvl(o.getDistributionMark())).append("\n型号").append(nvl(o.getModelNumber())).append("\n链接").append(nvl(o.getLink())).append("\n下单付款").append(nvl(o.getPaymentAmount())).append("\n后返金额").append(nvl(o.getRebateAmount())).append("\n地址").append(nvl(o.getAddress())).append("\n物流链接").append(nvl(o.getLogisticsLink())).append("\n订单号").append(nvl(o.getOrderId())).append("\n下单人").append(nvl(o.getBuyer())).append("\n下单时间").append(nvl(o.getOrderTime())).append("\n备注").append(nvl(o.getStatus())).append("\n━━━━━━━━━━━━\n");
sb.append(i).append(", 单:").append(nvl(o.getRemark())).append("\n分销标记").append(nvl(o.getDistributionMark())).append("\n型号").append(nvl(orderFullModel(o))).append("\n链接").append(nvl(o.getLink())).append("\n下单付款").append(nvl(o.getPaymentAmount())).append("\n后返金额").append(nvl(o.getRebateAmount())).append("\n地址").append(nvl(o.getAddress())).append("\n物流链接").append(nvl(o.getLogisticsLink())).append("\n订单号").append(nvl(o.getOrderId())).append("\n下单人").append(nvl(o.getBuyer())).append("\n下单时间").append(nvl(o.getOrderTime())).append("\n备注").append(nvl(o.getStatus())).append("\n━━━━━━━━━━━━\n");
}
return Collections.singletonList(sb.toString());
}
@@ -388,7 +391,7 @@ public class InstructionServiceImpl implements IInstructionService {
List<JDOrder> sorted = filtered.stream().sorted(Comparator.comparing(JDOrder::getRemark, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
StringBuilder sb = new StringBuilder();
for (JDOrder o : sorted) {
sb.append(nvl(o.getRemark())).append('\t').append(nvl(o.getOrderId())).append('\t').append(fmt(o.getOrderTime()).split(" ")[0]).append('\t').append(nvl(o.getModelNumber())).append('\t').append(nvl(o.getAddress())).append('\t').append(nvl(o.getLogisticsLink())).append('\t').append('\t').append(nvl(o.getBuyer())).append('\t').append(nvl(o.getPaymentAmount())).append('\t').append(nvl(o.getRebateAmount())).append('\t').append(mapDistribution(o.getDistributionMark())).append('\t').append(nvl(o.getStatus())).append("\n");
sb.append(nvl(o.getRemark())).append('\t').append(nvl(o.getOrderId())).append('\t').append(fmt(o.getOrderTime()).split(" ")[0]).append('\t').append(nvl(orderFullModel(o))).append('\t').append(nvl(o.getAddress())).append('\t').append(nvl(o.getLogisticsLink())).append('\t').append('\t').append(nvl(o.getBuyer())).append('\t').append(nvl(o.getPaymentAmount())).append('\t').append(nvl(o.getRebateAmount())).append('\t').append(mapDistribution(o.getDistributionMark())).append('\t').append(nvl(o.getStatus())).append("\n");
}
return Collections.singletonList(sb.toString());
}
@@ -422,7 +425,7 @@ public class InstructionServiceImpl implements IInstructionService {
String dm = e.getKey() != null ? e.getKey() : "未提供";
List<JDOrder> orders = e.getValue();
Map<String, Long> byModel = orders.stream().collect(Collectors.groupingBy(JDOrder::getModelNumber, Collectors.counting()));
Map<String, Long> byModel = orders.stream().collect(Collectors.groupingBy(this::orderFullModel, Collectors.counting()));
int totalCount = 0;
StringBuilder summary = new StringBuilder();
@@ -445,7 +448,7 @@ public class InstructionServiceImpl implements IInstructionService {
// 找到该型号价格最高的订单
for (JDOrder order : orders) {
if (model.equals(order.getModelNumber())) {
if (model.equals(orderFullModel(order))) {
JDOrder currentMax = groupMaxPriceOrders.get(model);
if (currentMax == null ||
(order.getPaymentAmount() != null &&
@@ -467,7 +470,7 @@ public class InstructionServiceImpl implements IInstructionService {
.append("单:").append(o.getRemark() != null ? o.getRemark() : "未提供").append("\n")
.append("备注:").append(o.getStatus() != null ? o.getStatus() : " ").append("\n")
.append("第三方单号:").append(o.getThirdPartyOrderNo() != null && !o.getThirdPartyOrderNo().isEmpty() ? o.getThirdPartyOrderNo() : "").append("\n")
.append("型号:").append(o.getModelNumber() != null ? o.getModelNumber() : "未提供").append("\n")
.append("型号:").append(o.getModelNumber() != null || o.getModelShop() != null ? orderFullModel(o) : "未提供").append("\n")
.append("地址:").append(o.getAddress() != null ? o.getAddress() : "未提供").append("\n")
.append("物流链接:\n").append(o.getLogisticsLink() != null ? o.getLogisticsLink() : "");
}
@@ -594,7 +597,7 @@ public class InstructionServiceImpl implements IInstructionService {
List<JDOrder> orders = e.getValue();
Map<String, Long> byModel = orders.stream()
.collect(Collectors.groupingBy(JDOrder::getModelNumber, Collectors.counting()));
.collect(Collectors.groupingBy(this::orderFullModel, Collectors.counting()));
int totalCount = 0;
StringBuilder summary = new StringBuilder();
@@ -616,7 +619,7 @@ public class InstructionServiceImpl implements IInstructionService {
// 找到该型号价格最高的订单
for (JDOrder order : orders) {
if (model.equals(order.getModelNumber())) {
if (model.equals(orderFullModel(order))) {
JDOrder currentMax = buyerMaxPriceOrders.get(model);
if (currentMax == null ||
(order.getPaymentAmount() != null &&
@@ -641,7 +644,7 @@ public class InstructionServiceImpl implements IInstructionService {
.append("单:").append(o.getRemark() != null ? o.getRemark() : "未提供").append("\n")
.append("备注:").append(o.getStatus() != null ? o.getStatus() : " ").append("\n")
.append("第三方单号:").append(o.getThirdPartyOrderNo() != null && !o.getThirdPartyOrderNo().isEmpty() ? o.getThirdPartyOrderNo() : "").append("\n")
.append("型号:").append(o.getModelNumber() != null ? o.getModelNumber() : "未提供").append("\n")
.append("型号:").append(o.getModelNumber() != null || o.getModelShop() != null ? orderFullModel(o) : "未提供").append("\n")
.append("地址:").append(o.getAddress() != null ? o.getAddress() : "未提供").append("\n")
.append("物流链接:\n").append(o.getLogisticsLink() != null ? o.getLogisticsLink() : "");
}
@@ -874,7 +877,7 @@ public class InstructionServiceImpl implements IInstructionService {
}
}
String jf = productJdConfigService.getJdUrlByProductModel(modelNumber);
String jf = productJdConfigService.getJdUrlByProductModel(jdOrderModelShopService.lookupModelBase(modelNumber));
StringBuilder order = new StringBuilder();
order.append(""+phone).append("\n").append(fenxiaoInfo).append("\n").append(modelNumber).append("\n").append(jf).append("\n").append(quantityStr).append("\n").append(address);
@@ -928,10 +931,11 @@ public class InstructionServiceImpl implements IInstructionService {
String rawModelToken = extractLastNonChineseToken(addressLine);
String modelNumber = sanitizeModel(rawModelToken);
String lookupModel = jdOrderModelShopService.lookupModelBase(modelNumber);
String cleanedAddress = addressLine.replaceAll("\\[.*?]", "").replace(rawModelToken, "").replaceAll("\\s+", " ").trim();
String fullAddress = cleanedAddress + " 安装派送联系" + phone + (suffix.isEmpty() ? "" : "" + suffix);
String jfLink = productJdConfigService.getJdUrlByProductModel(modelNumber);
String jfLink = productJdConfigService.getJdUrlByProductModel(lookupModel);
StringBuilder sheng = new StringBuilder();
sheng.append("\n").append(distributionMark).append("\n").append(modelNumber).append("\n").append(jfLink != null ? jfLink : "").append("\n")
@@ -956,7 +960,7 @@ public class InstructionServiceImpl implements IInstructionService {
String distributionMark = split[1];
String link = sanitizeLink(split[3]);
if ((link == null || link.isEmpty()) && shouldAutoFillLink(distributionMark)) {
String fetched = productJdConfigService.getJdUrlByProductModel(split[2]);
String fetched = productJdConfigService.getJdUrlByProductModel(jdOrderModelShopService.lookupModelBase(split[2]));
if (fetched != null && !fetched.isEmpty()) {
link = fetched;
}
@@ -1148,7 +1152,7 @@ public class InstructionServiceImpl implements IInstructionService {
}
// 获取转链链接
String jf = productJdConfigService.getJdUrlByProductModel(modelNumber);
String jf = productJdConfigService.getJdUrlByProductModel(jdOrderModelShopService.lookupModelBase(modelNumber));
// 构建"生"指令格式
StringBuilder sheng = new StringBuilder();
@@ -1453,7 +1457,7 @@ public class InstructionServiceImpl implements IInstructionService {
if (order == null) {
return null;
}
String model = order.getModelNumber();
String model = jdOrderModelShopService.fullModel(order);
String address = order.getAddress();
String logistics = extractOriginalLogisticsLinkNew(originalInput);
if (logistics == null && order.getLogisticsLink() != null) {
@@ -1515,6 +1519,7 @@ public class InstructionServiceImpl implements IInstructionService {
String originalInput = input.trim().replace("", "");
// 与 JDUtil.parseOrderFromText 一致的模板字段
JDOrder order = parseOrderFromText(originalInput);
jdOrderModelShopService.normalizeOrder(order);
// 字段校验并返回缺失项根据新模板格式单号存储在remark字段中
StringBuilder missing = new StringBuilder();
@@ -1658,7 +1663,7 @@ public class InstructionServiceImpl implements IInstructionService {
sb.append("第三方单号:").append(order.getThirdPartyOrderNo().trim()).append("\n");
}
sb.append("分销标记:").append(nvl(order.getDistributionMark())).append("\n");
sb.append("型号:").append(nvl(order.getModelNumber())).append("\n");
sb.append("型号:").append(nvl(jdOrderModelShopService.fullModel(order))).append("\n");
sb.append("下单人:").append(nvl(order.getBuyer())).append("\n");
sb.append("付款:").append(order.getPaymentAmount() != null ? order.getPaymentAmount().toString() : "").append("\n");
sb.append("后返:").append(order.getRebateAmount() != null ? order.getRebateAmount().toString() : "").append("\n");
@@ -1692,6 +1697,11 @@ public class InstructionServiceImpl implements IInstructionService {
return first;
}
/** 对外展示 / 录单文案用的完整型号(本体 + 店铺前缀) */
private String orderFullModel(JDOrder order) {
return order == null ? "" : jdOrderModelShopService.fullModel(order);
}
private boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
@@ -1730,7 +1740,7 @@ public class InstructionServiceImpl implements IInstructionService {
sb.append("下单地址(注意带分机):\n");
sb.append(order.getAddress() != null ? order.getAddress() : "").append("\n");
sb.append("—————————\n");
sb.append("型号:").append(order.getModelNumber() != null ? order.getModelNumber() : "").append("\n");
sb.append("型号:").append(orderFullModel(order)).append("\n");
sb.append("\n");
sb.append("下单人(需填):\n");
sb.append(order.getBuyer() != null ? order.getBuyer() : "").append("\n");
@@ -1772,7 +1782,7 @@ public class InstructionServiceImpl implements IInstructionService {
sb.append("分销标记:").append(order.getDistributionMark() != null ? order.getDistributionMark() : "").append("\n");
sb.append("第三方单号:").append(order.getThirdPartyOrderNo() != null ? order.getThirdPartyOrderNo() : "").append("\n");
sb.append("型号:\n");
sb.append(order.getModelNumber() != null ? order.getModelNumber() : "").append("\n");
sb.append(orderFullModel(order)).append("\n");
sb.append("链接:\n");
sb.append(order.getLink() != null ? order.getLink() : "").append("\n");
sb.append("下单付款:\n");

View File

@@ -0,0 +1,79 @@
package com.ruoyi.jarvis.service.impl;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.jarvis.domain.JDOrder;
import com.ruoyi.jarvis.domain.dto.QuickRecordModelShopOption;
import com.ruoyi.jarvis.mapper.JDOrderMapper;
import com.ruoyi.jarvis.service.IJDOrderModelShopService;
import com.ruoyi.jarvis.util.QuickRecordModelShopOptionUtil;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class JDOrderModelShopServiceImpl implements IJDOrderModelShopService {
@Autowired
private ISysConfigService sysConfigService;
@Autowired
private JDOrderMapper jdOrderMapper;
@Override
public List<QuickRecordModelShopOption> loadShopOptions() {
String raw = sysConfigService.selectConfigByKey(QuickRecordModelShopOptionUtil.CONFIG_KEY);
return QuickRecordModelShopOptionUtil.parseOptions(raw);
}
@Override
public void normalizeOrder(JDOrder order) {
QuickRecordModelShopOptionUtil.normalizeOrderModelShop(order, loadShopOptions());
}
@Override
public String fullModel(JDOrder order) {
return QuickRecordModelShopOptionUtil.fullModelNumber(order);
}
@Override
public String lookupModelBase(String rawModel) {
return QuickRecordModelShopOptionUtil.lookupModelBase(rawModel, loadShopOptions());
}
@Override
public Map<String, Object> migrateExistingOrders() {
List<QuickRecordModelShopOption> options = loadShopOptions();
Map<String, Object> result = new HashMap<>();
if (options.isEmpty()) {
result.put("updated", 0);
result.put("skipped", 0);
result.put("message", "未配置店铺选项quickRecord.modelShopOptions请先配置后再迁移");
return result;
}
List<JDOrder> candidates = jdOrderMapper.selectOrdersPendingModelShopMigration();
int updated = 0;
int skipped = 0;
for (JDOrder row : candidates) {
String beforeBase = StringUtils.trim(row.getModelNumber());
String beforeShop = StringUtils.trim(row.getModelShop());
normalizeOrder(row);
String afterBase = StringUtils.trim(row.getModelNumber());
String afterShop = StringUtils.trim(row.getModelShop());
if (beforeBase.equals(afterBase) && beforeShop.equals(afterShop)) {
skipped++;
continue;
}
jdOrderMapper.updateModelShopFields(row.getId(), row.getModelNumber(), row.getModelShop());
updated++;
}
result.put("updated", updated);
result.put("skipped", skipped);
result.put("total", candidates.size());
result.put("message", String.format("迁移完成:更新 %d 条,无变化 %d 条(共扫描 %d 条)", updated, skipped, candidates.size()));
return result;
}
}

View File

@@ -3,6 +3,7 @@ package com.ruoyi.jarvis.service.impl;
import com.ruoyi.jarvis.domain.JDOrder;
import com.ruoyi.jarvis.domain.dto.QuickRecordModelOption;
import com.ruoyi.jarvis.mapper.JDOrderMapper;
import com.ruoyi.jarvis.service.IJDOrderModelShopService;
import com.ruoyi.jarvis.service.IJDOrderProfitService;
import com.ruoyi.jarvis.service.IJDOrderService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -19,6 +20,9 @@ public class JDOrderServiceImpl implements IJDOrderService {
@Autowired
private IJDOrderProfitService jdOrderProfitService;
@Autowired
private IJDOrderModelShopService jdOrderModelShopService;
@Override
public List<JDOrder> selectJDOrderList(JDOrder jdOrder) {
return jdOrderMapper.selectJDOrderList(jdOrder);
@@ -36,12 +40,14 @@ public class JDOrderServiceImpl implements IJDOrderService {
@Override
public int insertJDOrder(JDOrder jdOrder) {
jdOrderModelShopService.normalizeOrder(jdOrder);
jdOrderProfitService.recalculate(jdOrder);
return jdOrderMapper.insertJDOrder(jdOrder);
}
@Override
public int updateJDOrder(JDOrder jdOrder) {
jdOrderModelShopService.normalizeOrder(jdOrder);
return jdOrderMapper.updateJDOrder(jdOrder);
}
@@ -87,6 +93,11 @@ public class JDOrderServiceImpl implements IJDOrderService {
public List<QuickRecordModelOption> selectQuickRecordModelOptions() {
return jdOrderMapper.selectQuickRecordModelOptions();
}
@Override
public java.util.Map<String, Object> migrateModelShopSplit() {
return jdOrderModelShopService.migrateExistingOrders();
}
}

View File

@@ -2,6 +2,7 @@ package com.ruoyi.jarvis.util;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.jarvis.domain.dto.QuickRecordModelShopOption;
import com.ruoyi.jarvis.domain.JDOrder;
import java.util.ArrayList;
import java.util.Collections;
@@ -88,4 +89,58 @@ public final class QuickRecordModelShopOptionUtil {
}
return new String[] { full, "" };
}
public static String fullModelNumber(String base, String shop) {
String b = StringUtils.trim(base);
String s = StringUtils.trim(shop);
if (StringUtils.isEmpty(b)) {
return s;
}
if (StringUtils.isEmpty(s)) {
return b;
}
if (b.endsWith(s)) {
return b;
}
return b + s;
}
public static String fullModelNumber(JDOrder order) {
if (order == null) {
return "";
}
return fullModelNumber(order.getModelNumber(), order.getModelShop());
}
/**
* 落库前归一化model_number 仅存本体model_shop 存店铺前缀。
* 若 model_shop 已有值则仅纠正 model_number 仍带后缀的情况。
*/
public static void normalizeOrderModelShop(JDOrder order, List<QuickRecordModelShopOption> options) {
if (order == null) {
return;
}
String base = StringUtils.trim(order.getModelNumber());
String shop = StringUtils.trim(order.getModelShop());
if (StringUtils.isNotEmpty(shop)) {
if (StringUtils.isNotEmpty(base) && base.endsWith(shop) && base.length() > shop.length()) {
order.setModelNumber(base.substring(0, base.length() - shop.length()));
}
order.setModelShop(shop);
return;
}
if (StringUtils.isEmpty(base)) {
order.setModelShop("");
return;
}
String[] split = splitModelSuffix(base, options);
order.setModelNumber(split[0]);
order.setModelShop(split[1]);
}
/** 京粉/型号配置 lookup 用本体型号 */
public static String lookupModelBase(String rawModel, List<QuickRecordModelShopOption> options) {
String[] split = splitModelSuffix(StringUtils.trim(rawModel), options);
return split[0];
}
}

View File

@@ -7,6 +7,7 @@
<result property="remark" column="remark"/>
<result property="distributionMark" column="distribution_mark"/>
<result property="modelNumber" column="model_number"/>
<result property="modelShop" column="model_shop"/>
<result property="link" column="link"/>
<result property="paymentAmount" column="payment_amount"/>
<result property="rebateAmount" column="rebate_amount"/>
@@ -46,7 +47,7 @@
</resultMap>
<sql id="selectJDOrderBase">
select id, remark, distribution_mark, model_number, link, payment_amount, rebate_amount,
select id, remark, distribution_mark, model_number, model_shop, link, payment_amount, rebate_amount,
address, logistics_link, order_id, buyer, order_time, create_time, update_time, status, is_count_enabled, third_party_order_no, jingfen_actual_price,
is_refunded, refund_date, is_refund_received, refund_received_date, is_rebate_received, rebate_received_date,
is_price_protected, price_protected_date, is_invoice_opened, invoice_opened_date, is_review_posted, review_posted_date,
@@ -67,7 +68,13 @@
)
</if>
<if test="distributionMark != null and distributionMark != ''"> and distribution_mark = #{distributionMark}</if>
<if test="modelNumber != null and modelNumber != ''"> and model_number like concat('%', #{modelNumber}, '%')</if>
<if test="modelNumber != null and modelNumber != ''">
and (
model_number like concat('%', #{modelNumber}, '%')
or concat(IFNULL(model_number, ''), IFNULL(model_shop, '')) like concat('%', #{modelNumber}, '%')
)
</if>
<if test="modelShop != null and modelShop != ''"> and model_shop = #{modelShop}</if>
<if test="params.modelNumberExcludeList != null and params.modelNumberExcludeList.size() > 0">
<foreach collection="params.modelNumberExcludeList" item="ex">
and (model_number is null or model_number not like concat('%', #{ex}, '%'))
@@ -120,7 +127,13 @@
)
</if>
<if test="distributionMark != null and distributionMark != ''"> and distribution_mark = #{distributionMark}</if>
<if test="modelNumber != null and modelNumber != ''"> and model_number like concat('%', #{modelNumber}, '%')</if>
<if test="modelNumber != null and modelNumber != ''">
and (
model_number like concat('%', #{modelNumber}, '%')
or concat(IFNULL(model_number, ''), IFNULL(model_shop, '')) like concat('%', #{modelNumber}, '%')
)
</if>
<if test="modelShop != null and modelShop != ''"> and model_shop = #{modelShop}</if>
<if test="params.modelNumberExcludeList != null and params.modelNumberExcludeList.size() > 0">
<foreach collection="params.modelNumberExcludeList" item="ex">
and (model_number is null or model_number not like concat('%', #{ex}, '%'))
@@ -177,7 +190,7 @@
<insert id="insertJDOrder" parameterType="JDOrder" useGeneratedKeys="true" keyProperty="id">
insert into jd_order (
remark, distribution_mark, model_number, link,
remark, distribution_mark, model_number, model_shop, link,
payment_amount, rebate_amount, address, logistics_link,
tencent_doc_pushed, tencent_doc_push_time,
order_id, buyer, order_time, create_time, update_time, status, is_count_enabled, third_party_order_no, jingfen_actual_price,
@@ -185,7 +198,7 @@
is_price_protected, price_protected_date, is_invoice_opened, invoice_opened_date, is_review_posted, review_posted_date,
selling_price_type, selling_price, profit, selling_price_manual, profit_manual, extra_cost
) values (
#{remark}, #{distributionMark}, #{modelNumber}, #{link},
#{remark}, #{distributionMark}, #{modelNumber}, #{modelShop}, #{link},
#{paymentAmount}, #{rebateAmount}, #{address}, #{logisticsLink},
0, null,
#{orderId}, #{buyer}, #{orderTime}, now(), now(), #{status}, #{isCountEnabled}, #{thirdPartyOrderNo}, #{jingfenActualPrice},
@@ -201,6 +214,7 @@
<if test="remark != null"> remark = #{remark},</if>
<if test="distributionMark != null"> distribution_mark = #{distributionMark},</if>
<if test="modelNumber != null"> model_number = #{modelNumber},</if>
<if test="modelShop != null"> model_shop = #{modelShop},</if>
<if test="link != null"> link = #{link},</if>
<if test="paymentAmount != null"> payment_amount = #{paymentAmount},</if>
<if test="rebateAmount != null"> rebate_amount = #{rebateAmount},</if>
@@ -305,24 +319,45 @@
<resultMap id="QuickRecordModelOptionResult" type="com.ruoyi.jarvis.domain.dto.QuickRecordModelOption">
<result property="modelNumber" column="model_number"/>
<result property="modelShop" column="model_shop"/>
<result property="lastPaymentAmount" column="last_payment_amount"/>
<result property="lastRebateAmount" column="last_rebate_amount"/>
</resultMap>
<select id="selectQuickRecordModelOptions" resultMap="QuickRecordModelOptionResult">
select o.model_number as model_number,
o.model_shop as model_shop,
o.payment_amount as last_payment_amount,
o.rebate_amount as last_rebate_amount
from jd_order o
inner join (
select trim(model_number) as m, max(id) as mid
select trim(IFNULL(model_number, '')) as m,
trim(IFNULL(model_shop, '')) as s,
max(id) as mid
from jd_order
where model_number is not null and trim(model_number) != ''
group by trim(model_number)
) t on trim(o.model_number) = t.m and o.id = t.mid
group by trim(IFNULL(model_number, '')), trim(IFNULL(model_shop, ''))
) t on trim(IFNULL(o.model_number, '')) = t.m
and trim(IFNULL(o.model_shop, '')) = t.s
and o.id = t.mid
order by o.id desc
</select>
<select id="selectOrdersPendingModelShopMigration" resultMap="JDOrderResult">
<include refid="selectJDOrderBase"/>
where model_number is not null
and trim(model_number) != ''
order by id asc
</select>
<update id="updateModelShopFields">
update jd_order
set model_number = #{modelNumber},
model_shop = #{modelShop},
update_time = now()
where id = #{id}
</update>
</mapper>

View File

@@ -0,0 +1,2 @@
-- 京东订单:型号店铺短前缀(与 model_number 拆分存储,便于筛选;完整对外型号 = model_number + model_shop
ALTER TABLE jd_order ADD COLUMN model_shop VARCHAR(64) DEFAULT NULL COMMENT '型号店铺短前缀(如海尔厨房)';