Compare commits
24 Commits
810625e0a9
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2558b91250 | ||
|
|
546cd8eb04 | ||
|
|
e890039dea | ||
|
|
1f6625f296 | ||
|
|
90e6904b5d | ||
|
|
0022a197cc | ||
|
|
8d3f1337e9 | ||
|
|
67e6723685 | ||
|
|
6412168cc6 | ||
|
|
a8a6d57a72 | ||
|
|
8f8333e324 | ||
|
|
b107eece07 | ||
|
|
8fcd7be160 | ||
|
|
4aec0177dd | ||
|
|
379a11ae63 | ||
|
|
0963b8af59 | ||
|
|
6fa6cf624e | ||
|
|
7ef9c16ae7 | ||
|
|
77776802f2 | ||
|
|
8770ea92ed | ||
|
|
0a3a9c46f6 | ||
|
|
17ec7fa131 | ||
|
|
746be8c633 | ||
|
|
46e6143a87 |
@@ -40,6 +40,12 @@ public class ErpGoofishOrderController extends BaseController {
|
|||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:list')")
|
||||||
|
@GetMapping("/stats/rrsLogistics")
|
||||||
|
public AjaxResult rrsLogisticsStats() {
|
||||||
|
return AjaxResult.success(erpGoofishOrderService.selectRrsJdLinkedLogisticsStats());
|
||||||
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:list')")
|
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:list')")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo list(ErpGoofishOrder query) {
|
public TableDataInfo list(ErpGoofishOrder query) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import com.ruoyi.common.core.controller.BaseController;
|
|||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
import com.ruoyi.jarvis.domain.OrderRows;
|
import com.ruoyi.jarvis.domain.OrderRows;
|
||||||
|
import com.ruoyi.jarvis.service.IGoodsInfoService;
|
||||||
import com.ruoyi.jarvis.service.IOrderRowsService;
|
import com.ruoyi.jarvis.service.IOrderRowsService;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
@@ -32,6 +33,9 @@ public class OrderRowsController extends BaseController
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IOrderRowsService orderRowsService;
|
private IOrderRowsService orderRowsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IGoodsInfoService goodsInfoService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SuperAdminService superAdminService;
|
private SuperAdminService superAdminService;
|
||||||
|
|
||||||
@@ -127,7 +131,11 @@ public class OrderRowsController extends BaseController
|
|||||||
@GetMapping(value = "/{id}")
|
@GetMapping(value = "/{id}")
|
||||||
public AjaxResult getInfo(@PathVariable("id") String id)
|
public AjaxResult getInfo(@PathVariable("id") String id)
|
||||||
{
|
{
|
||||||
return success(orderRowsService.selectOrderRowsById(id));
|
OrderRows orderRows = orderRowsService.selectOrderRowsById(id);
|
||||||
|
if (orderRows != null && orderRows.getGoodsInfoId() != null) {
|
||||||
|
orderRows.setGoodsInfo(goodsInfoService.selectGoodsInfoById(orderRows.getGoodsInfoId()));
|
||||||
|
}
|
||||||
|
return success(orderRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package com.ruoyi.web.controller.publicapi;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Anonymous;
|
||||||
|
import com.ruoyi.common.annotation.RateLimiter;
|
||||||
|
import com.ruoyi.common.constant.CacheConstants;
|
||||||
|
import com.ruoyi.common.enums.LimitType;
|
||||||
|
import com.ruoyi.jarvis.domain.GoodsInfo;
|
||||||
|
import com.ruoyi.jarvis.domain.OrderRows;
|
||||||
|
import com.ruoyi.jarvis.domain.dto.PromoterOrderInfoVO;
|
||||||
|
import com.ruoyi.jarvis.enums.ValidCodeConverter;
|
||||||
|
import com.ruoyi.jarvis.service.IGoodsInfoService;
|
||||||
|
import com.ruoyi.jarvis.service.IOrderRowsService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 京东开放接口(免登录,路径统一 /open/jd/)
|
||||||
|
*/
|
||||||
|
@Anonymous
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/open/jd")
|
||||||
|
public class PublicPromoterOrderController {
|
||||||
|
|
||||||
|
private static final String DEFAULT_SHOP_LOGO = "https://www.jd.com/favicon.ico";
|
||||||
|
private static final SimpleDateFormat DATE_FMT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOrderRowsService orderRowsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IGoodsInfoService goodsInfoService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跟团订单查询(兼容 jiadiantemai 接口格式)
|
||||||
|
*/
|
||||||
|
@GetMapping("/queryTkOrder")
|
||||||
|
@RateLimiter(key = CacheConstants.RATE_LIMIT_KEY, time = 60, count = 30, limitType = LimitType.IP)
|
||||||
|
public Map<String, Object> queryTkOrder(
|
||||||
|
@RequestParam String orderId,
|
||||||
|
@RequestParam(required = false) String t) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
String trimmedOrderId = orderId != null ? orderId.trim() : "";
|
||||||
|
if (trimmedOrderId.isEmpty()) {
|
||||||
|
result.put("code", 200);
|
||||||
|
result.put("count", 0);
|
||||||
|
result.put("msg", "请输入订单编号");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OrderRows> rows = orderRowsService.selectOrderRowsByOrderNo(trimmedOrderId);
|
||||||
|
if (rows == null || rows.isEmpty()) {
|
||||||
|
result.put("code", 200);
|
||||||
|
result.put("count", 0);
|
||||||
|
result.put("msg", "未查找到对应订单信息~");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Long> goodsInfoIds = new HashSet<>();
|
||||||
|
for (OrderRows row : rows) {
|
||||||
|
if (row.getGoodsInfoId() != null) {
|
||||||
|
goodsInfoIds.add(row.getGoodsInfoId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<Long, GoodsInfo> goodsInfoMap = goodsInfoService.selectGoodsInfoMapByIds(goodsInfoIds);
|
||||||
|
|
||||||
|
List<PromoterOrderInfoVO> orderInfoList = new ArrayList<>();
|
||||||
|
ValidCodeConverter validCodeConverter = new ValidCodeConverter();
|
||||||
|
for (OrderRows row : rows) {
|
||||||
|
GoodsInfo goodsInfo = row.getGoodsInfoId() != null
|
||||||
|
? goodsInfoMap.get(row.getGoodsInfoId()) : null;
|
||||||
|
orderInfoList.add(toPromoterOrderInfo(row, goodsInfo, validCodeConverter));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderInfoList.isEmpty()) {
|
||||||
|
result.put("code", 200);
|
||||||
|
result.put("count", 0);
|
||||||
|
result.put("msg", "未查找到对应订单信息~");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.put("code", 200);
|
||||||
|
result.put("orderInfoList", orderInfoList);
|
||||||
|
result.put("msg", "查询成功");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PromoterOrderInfoVO toPromoterOrderInfo(OrderRows row, GoodsInfo goodsInfo,
|
||||||
|
ValidCodeConverter validCodeConverter) {
|
||||||
|
PromoterOrderInfoVO vo = new PromoterOrderInfoVO();
|
||||||
|
String shopName = goodsInfo != null && goodsInfo.getShopName() != null && !goodsInfo.getShopName().isEmpty()
|
||||||
|
? goodsInfo.getShopName() : "京东商城";
|
||||||
|
vo.setShopName(shopName);
|
||||||
|
vo.setShopLogo(DEFAULT_SHOP_LOGO);
|
||||||
|
vo.setOrderSource("京东");
|
||||||
|
vo.setTraceTypeStr(row.getTraceType() != null && row.getTraceType() == 2 ? "同店" : "跨店");
|
||||||
|
if (row.getParentId() != null && row.getParentId() > 0) {
|
||||||
|
vo.setParentId(String.valueOf(row.getParentId()));
|
||||||
|
}
|
||||||
|
if (row.getOrderId() != null) {
|
||||||
|
vo.setOrderId(String.valueOf(row.getOrderId()));
|
||||||
|
}
|
||||||
|
vo.setValidCodeMsg(validCodeConverter.getCodeDescription(row.getValidCode()));
|
||||||
|
if (goodsInfo != null && goodsInfo.getImageUrl() != null && !goodsInfo.getImageUrl().isEmpty()) {
|
||||||
|
vo.setSkuImageUrl(goodsInfo.getImageUrl());
|
||||||
|
} else if (row.getSkuId() != null) {
|
||||||
|
vo.setSkuImageUrl("https://img14.360buyimg.com/n5/s450x450_" + row.getSkuId() + ".jpg");
|
||||||
|
}
|
||||||
|
vo.setSkuName(row.getSkuName());
|
||||||
|
if (row.getSkuId() != null) {
|
||||||
|
vo.setSkuId(String.valueOf(row.getSkuId()));
|
||||||
|
}
|
||||||
|
vo.setItemId(row.getItemId());
|
||||||
|
vo.setSkuNum(row.getSkuNum() != null ? row.getSkuNum() : 1);
|
||||||
|
vo.setCosPrice(formatPrice(row));
|
||||||
|
vo.setOrderTime(formatDate(row.getOrderTime()));
|
||||||
|
vo.setFinishTime(formatDate(row.getFinishTime()));
|
||||||
|
Double proPrice = row.getProPriceAmount();
|
||||||
|
if (proPrice != null && proPrice > 0) {
|
||||||
|
vo.setProPriceAmount(String.format("%.2f", proPrice));
|
||||||
|
} else {
|
||||||
|
vo.setProPriceAmount("0.00");
|
||||||
|
}
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatPrice(OrderRows row) {
|
||||||
|
Double price = row.getActualCosPrice();
|
||||||
|
if (price == null || price <= 0) {
|
||||||
|
price = row.getEstimateCosPrice();
|
||||||
|
}
|
||||||
|
if (price == null) {
|
||||||
|
return "0.00";
|
||||||
|
}
|
||||||
|
return String.format("%.2f", price);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatDate(java.util.Date date) {
|
||||||
|
if (date == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
synchronized (DATE_FMT) {
|
||||||
|
return DATE_FMT.format(date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,13 +9,20 @@ import java.util.Map;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.ruoyi.jarvis.domain.GroupRebateExcelUpload;
|
import com.ruoyi.jarvis.domain.GroupRebateExcelUpload;
|
||||||
import com.ruoyi.jarvis.domain.OrderRows;
|
import com.ruoyi.jarvis.domain.OrderRows;
|
||||||
import com.ruoyi.jarvis.service.IGroupRebateExcelUploadService;
|
import com.ruoyi.jarvis.service.IGroupRebateExcelUploadService;
|
||||||
import com.ruoyi.jarvis.service.impl.GroupRebateExcelImportService;
|
import com.ruoyi.jarvis.service.impl.GroupRebateExcelImportService;
|
||||||
import com.ruoyi.jarvis.service.IOrderRowsService;
|
import com.ruoyi.jarvis.service.IOrderRowsService;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.file.FileUtils;
|
import com.ruoyi.common.utils.file.FileUtils;
|
||||||
|
import com.ruoyi.common.utils.http.HttpUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
@@ -27,7 +34,11 @@ import com.ruoyi.common.enums.BusinessType;
|
|||||||
import com.ruoyi.jarvis.domain.JDOrder;
|
import com.ruoyi.jarvis.domain.JDOrder;
|
||||||
import com.ruoyi.jarvis.domain.dto.JDOrderSimpleDTO;
|
import com.ruoyi.jarvis.domain.dto.JDOrderSimpleDTO;
|
||||||
import com.ruoyi.jarvis.domain.dto.QuickRecordModelOption;
|
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.jarvis.service.IJDOrderProfitService;
|
||||||
|
import com.ruoyi.system.service.ISysConfigService;
|
||||||
import com.ruoyi.jarvis.service.IJDOrderService;
|
import com.ruoyi.jarvis.service.IJDOrderService;
|
||||||
import com.ruoyi.jarvis.service.IInstructionService;
|
import com.ruoyi.jarvis.service.IInstructionService;
|
||||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||||
@@ -43,6 +54,14 @@ import com.ruoyi.common.core.page.TableDataInfo;
|
|||||||
public class JDOrderListController extends BaseController
|
public class JDOrderListController extends BaseController
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static final String JARVIS_JAVA_SKEY = "2192057370ef8140c201079969c956a3";
|
||||||
|
|
||||||
|
@Value("${jarvis.server.jarvis-java.base-url:http://127.0.0.1:6666}")
|
||||||
|
private String jarvisJavaBaseUrl;
|
||||||
|
|
||||||
|
@Value("${jarvis.server.jarvis-java.jd-api-path:/jd}")
|
||||||
|
private String jdApiPath;
|
||||||
|
|
||||||
private final IJDOrderService jdOrderService;
|
private final IJDOrderService jdOrderService;
|
||||||
private final IJDOrderProfitService jdOrderProfitService;
|
private final IJDOrderProfitService jdOrderProfitService;
|
||||||
private final IOrderRowsService orderRowsService;
|
private final IOrderRowsService orderRowsService;
|
||||||
@@ -50,17 +69,27 @@ public class JDOrderListController extends BaseController
|
|||||||
private final GroupRebateExcelImportService groupRebateExcelImportService;
|
private final GroupRebateExcelImportService groupRebateExcelImportService;
|
||||||
private final IGroupRebateExcelUploadService groupRebateExcelUploadService;
|
private final IGroupRebateExcelUploadService groupRebateExcelUploadService;
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
private final ISysConfigService sysConfigService;
|
||||||
|
private final IJDOrderModelShopService jdOrderModelShopService;
|
||||||
|
|
||||||
public JDOrderListController(IJDOrderService jdOrderService, IJDOrderProfitService jdOrderProfitService,
|
public JDOrderListController(IJDOrderService jdOrderService, IJDOrderProfitService jdOrderProfitService,
|
||||||
IOrderRowsService orderRowsService,
|
IOrderRowsService orderRowsService,
|
||||||
IInstructionService instructionService,
|
IInstructionService instructionService,
|
||||||
GroupRebateExcelImportService groupRebateExcelImportService,
|
GroupRebateExcelImportService groupRebateExcelImportService,
|
||||||
IGroupRebateExcelUploadService groupRebateExcelUploadService) {
|
IGroupRebateExcelUploadService groupRebateExcelUploadService,
|
||||||
|
ObjectMapper objectMapper,
|
||||||
|
ISysConfigService sysConfigService,
|
||||||
|
IJDOrderModelShopService jdOrderModelShopService) {
|
||||||
this.jdOrderService = jdOrderService;
|
this.jdOrderService = jdOrderService;
|
||||||
this.jdOrderProfitService = jdOrderProfitService;
|
this.jdOrderProfitService = jdOrderProfitService;
|
||||||
this.orderRowsService = orderRowsService;
|
this.orderRowsService = orderRowsService;
|
||||||
this.instructionService = instructionService;
|
this.instructionService = instructionService;
|
||||||
this.groupRebateExcelImportService = groupRebateExcelImportService;
|
this.groupRebateExcelImportService = groupRebateExcelImportService;
|
||||||
this.groupRebateExcelUploadService = groupRebateExcelUploadService;
|
this.groupRebateExcelUploadService = groupRebateExcelUploadService;
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
this.sysConfigService = sysConfigService;
|
||||||
|
this.jdOrderModelShopService = jdOrderModelShopService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,6 +137,8 @@ public class JDOrderListController extends BaseController
|
|||||||
query.getParams().put("rebateWithoutUploadLink", true);
|
query.getParams().put("rebateWithoutUploadLink", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyModelNumberExcludeFilter(query);
|
||||||
|
|
||||||
java.util.List<JDOrder> list;
|
java.util.List<JDOrder> list;
|
||||||
if (orderBy != null && !orderBy.isEmpty()) {
|
if (orderBy != null && !orderBy.isEmpty()) {
|
||||||
// 设置排序参数
|
// 设置排序参数
|
||||||
@@ -130,10 +161,12 @@ public class JDOrderListController extends BaseController
|
|||||||
jdOrder.setProPriceAmount(orderRows.getProPriceAmount());
|
jdOrder.setProPriceAmount(orderRows.getProPriceAmount());
|
||||||
jdOrder.setFinishTime(orderRows.getFinishTime());
|
jdOrder.setFinishTime(orderRows.getFinishTime());
|
||||||
jdOrder.setOrderStatus(orderRows.getValidCode());
|
jdOrder.setOrderStatus(orderRows.getValidCode());
|
||||||
|
jdOrder.setExpressStatus(orderRows.getExpressStatus());
|
||||||
} else {
|
} else {
|
||||||
jdOrder.setProPriceAmount(0.0);
|
jdOrder.setProPriceAmount(0.0);
|
||||||
jdOrder.setFinishTime(null);
|
jdOrder.setFinishTime(null);
|
||||||
jdOrder.setOrderStatus(null);
|
jdOrder.setOrderStatus(null);
|
||||||
|
jdOrder.setExpressStatus(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 过滤掉完成时间为空的订单
|
// 过滤掉完成时间为空的订单
|
||||||
@@ -148,9 +181,11 @@ public class JDOrderListController extends BaseController
|
|||||||
jdOrder.setProPriceAmount(orderRows.getProPriceAmount());
|
jdOrder.setProPriceAmount(orderRows.getProPriceAmount());
|
||||||
jdOrder.setFinishTime(orderRows.getFinishTime());
|
jdOrder.setFinishTime(orderRows.getFinishTime());
|
||||||
jdOrder.setOrderStatus(orderRows.getValidCode());
|
jdOrder.setOrderStatus(orderRows.getValidCode());
|
||||||
|
jdOrder.setExpressStatus(orderRows.getExpressStatus());
|
||||||
} else {
|
} else {
|
||||||
jdOrder.setProPriceAmount(0.0);
|
jdOrder.setProPriceAmount(0.0);
|
||||||
jdOrder.setOrderStatus(null);
|
jdOrder.setOrderStatus(null);
|
||||||
|
jdOrder.setExpressStatus(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,6 +202,26 @@ public class JDOrderListController extends BaseController
|
|||||||
return AjaxResult.success(options);
|
return AjaxResult.success(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快捷录单页:型号后缀店铺下拉(系统参数 quickRecord.modelShopOptions,每行格式:短前缀(完整店名))
|
||||||
|
*/
|
||||||
|
@GetMapping("/quickRecord/shopOptions")
|
||||||
|
public AjaxResult quickRecordShopOptions() {
|
||||||
|
String raw = sysConfigService.selectConfigByKey(QuickRecordModelShopOptionUtil.CONFIG_KEY);
|
||||||
|
List<QuickRecordModelShopOption> options = QuickRecordModelShopOptionUtil.parseOptions(raw);
|
||||||
|
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:按「单号/订单号」匹配系统订单,将「是否返现」「总共返现」等写入后返备注(可多次导入累加);文件落盘并记上传记录。
|
* 导入跟团返现类 Excel:按「单号/订单号」匹配系统订单,将「是否返现」「总共返现」等写入后返备注(可多次导入累加);文件落盘并记上传记录。
|
||||||
*/
|
*/
|
||||||
@@ -258,6 +313,8 @@ public class JDOrderListController extends BaseController
|
|||||||
{
|
{
|
||||||
String fileName = "JD订单数据";
|
String fileName = "JD订单数据";
|
||||||
|
|
||||||
|
applyModelNumberExcludeFilter(jdOrder);
|
||||||
|
|
||||||
List<JDOrder> list = jdOrderService.selectJDOrderList(jdOrder);
|
List<JDOrder> list = jdOrderService.selectJDOrderList(jdOrder);
|
||||||
|
|
||||||
// 设置响应头,指定文件名
|
// 设置响应头,指定文件名
|
||||||
@@ -292,15 +349,54 @@ public class JDOrderListController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改JD订单
|
* 修改JD订单(PUT body 使用 JsonNode:extraCost / extra_cost 从原始 JSON 显式写入实体,
|
||||||
|
* 避免个别 Jackson + Lombok 场景下 treeToValue 未映射导致重算利润仍按 0 计算)
|
||||||
*/
|
*/
|
||||||
@Log(title = "JD订单", businessType = BusinessType.UPDATE)
|
@Log(title = "JD订单", businessType = BusinessType.UPDATE)
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public AjaxResult edit(@RequestBody JDOrder jdOrder)
|
public AjaxResult edit(@RequestBody JsonNode root) throws JsonProcessingException {
|
||||||
{
|
JDOrder jdOrder = objectMapper.treeToValue(root, JDOrder.class);
|
||||||
|
applyExtraCostFromPayload(root, jdOrder);
|
||||||
|
jdOrderModelShopService.normalizeOrder(jdOrder);
|
||||||
jdOrderProfitService.recalculate(jdOrder);
|
jdOrderProfitService.recalculate(jdOrder);
|
||||||
jdOrder.getParams().put("applyProfitFields", Boolean.TRUE);
|
jdOrder.getParams().put("applyProfitFields", Boolean.TRUE);
|
||||||
return toAjax(jdOrderService.updateJDOrder(jdOrder));
|
int rows = jdOrderService.updateJDOrder(jdOrder);
|
||||||
|
if (rows <= 0) {
|
||||||
|
return AjaxResult.error("更新失败或订单不存在");
|
||||||
|
}
|
||||||
|
return AjaxResult.success(jdOrderService.selectJDOrderById(jdOrder.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyExtraCostFromPayload(JsonNode root, JDOrder order) {
|
||||||
|
if (root == null || order == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JsonNode n = root.get("extraCost");
|
||||||
|
if (readExtraCostNumber(n, order)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
n = root.get("extra_cost");
|
||||||
|
readExtraCostNumber(n, order);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return true 已从节点解析并写入 order */
|
||||||
|
private static boolean readExtraCostNumber(JsonNode n, JDOrder order) {
|
||||||
|
if (n == null || n.isNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (n.isNumber()) {
|
||||||
|
order.setExtraCost(n.asDouble());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (n.isTextual()) {
|
||||||
|
try {
|
||||||
|
order.setExtraCost(Double.parseDouble(n.asText().trim()));
|
||||||
|
return true;
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -522,9 +618,7 @@ public class JDOrderListController extends BaseController
|
|||||||
if (query.getModelNumber() != null && !query.getModelNumber().trim().isEmpty()) {
|
if (query.getModelNumber() != null && !query.getModelNumber().trim().isEmpty()) {
|
||||||
query.setModelNumber(query.getModelNumber().trim());
|
query.setModelNumber(query.getModelNumber().trim());
|
||||||
}
|
}
|
||||||
if (query.getModelNumberExclude() != null && !query.getModelNumberExclude().trim().isEmpty()) {
|
applyModelNumberExcludeFilter(query);
|
||||||
query.setModelNumberExclude(query.getModelNumberExclude().trim());
|
|
||||||
}
|
|
||||||
if (query.getBuyer() != null && !query.getBuyer().trim().isEmpty()) {
|
if (query.getBuyer() != null && !query.getBuyer().trim().isEmpty()) {
|
||||||
query.setBuyer(query.getBuyer().trim());
|
query.setBuyer(query.getBuyer().trim());
|
||||||
}
|
}
|
||||||
@@ -575,8 +669,8 @@ public class JDOrderListController extends BaseController
|
|||||||
String duoduoOrderNo = o.getThirdPartyOrderNo() != null && !o.getThirdPartyOrderNo().trim().isEmpty()
|
String duoduoOrderNo = o.getThirdPartyOrderNo() != null && !o.getThirdPartyOrderNo().trim().isEmpty()
|
||||||
? o.getThirdPartyOrderNo() : (o.getRemark() != null ? o.getRemark() : "");
|
? o.getThirdPartyOrderNo() : (o.getRemark() != null ? o.getRemark() : "");
|
||||||
|
|
||||||
// 型号
|
// 型号(对外完整型号 = 本体 + 店铺前缀)
|
||||||
String modelNumber = o.getModelNumber() != null ? o.getModelNumber() : "";
|
String modelNumber = QuickRecordModelShopOptionUtil.fullModelNumber(o);
|
||||||
|
|
||||||
// 数量(固定为1)
|
// 数量(固定为1)
|
||||||
String quantity = "1";
|
String quantity = "1";
|
||||||
@@ -639,4 +733,72 @@ public class JDOrderListController extends BaseController
|
|||||||
return AjaxResult.error("生成失败: " + e.getMessage());
|
return AjaxResult.error("生成失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 型号不含:支持逗号、中文逗号、空格、换行分隔的多个关键词,型号不得包含任一关键词。
|
||||||
|
*/
|
||||||
|
private void applyModelNumberExcludeFilter(JDOrder query) {
|
||||||
|
if (query == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> terms = parseModelNumberExcludeTerms(query.getModelNumberExclude());
|
||||||
|
if (!terms.isEmpty()) {
|
||||||
|
query.getParams().put("modelNumberExcludeList", terms);
|
||||||
|
}
|
||||||
|
query.setModelNumberExclude(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> parseModelNumberExcludeTerms(String raw) {
|
||||||
|
List<String> out = new ArrayList<>();
|
||||||
|
if (StringUtils.isEmpty(raw)) {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
for (String part : raw.split("[,,\\s\\n]+")) {
|
||||||
|
String t = part.trim();
|
||||||
|
if (!t.isEmpty() && !out.contains(t)) {
|
||||||
|
out.add(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回填京粉订单 goodsInfo(店铺名、商品图)
|
||||||
|
* Body: { "orderIds": "352543902480387,3525433002460987" }
|
||||||
|
* 或: { "missing": true, "limit": 100 }
|
||||||
|
*/
|
||||||
|
@Log(title = "京粉订单goodsInfo回填", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/orderRows/backfillGoodsInfo")
|
||||||
|
public AjaxResult backfillGoodsInfo(@RequestBody Map<String, Object> body) {
|
||||||
|
try {
|
||||||
|
JSONObject param = new JSONObject();
|
||||||
|
param.put("skey", JARVIS_JAVA_SKEY);
|
||||||
|
if (body != null) {
|
||||||
|
if (body.get("orderIds") != null) {
|
||||||
|
param.put("orderIds", body.get("orderIds"));
|
||||||
|
}
|
||||||
|
if (body.get("missing") != null) {
|
||||||
|
param.put("missing", body.get("missing"));
|
||||||
|
}
|
||||||
|
if (body.get("limit") != null) {
|
||||||
|
param.put("limit", body.get("limit"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String url = jarvisJavaBaseUrl + jdApiPath + "/backfillGoodsInfo";
|
||||||
|
String resp = HttpUtils.sendJsonPost(url, param.toJSONString());
|
||||||
|
if (StringUtils.isEmpty(resp)) {
|
||||||
|
return AjaxResult.error("Jarvis 服务无响应,请检查 jarvis.server.jarvis-java.base-url");
|
||||||
|
}
|
||||||
|
Object parsed = JSON.parse(resp);
|
||||||
|
if (parsed instanceof JSONObject) {
|
||||||
|
JSONObject obj = (JSONObject) parsed;
|
||||||
|
if (obj.containsKey("error")) {
|
||||||
|
return AjaxResult.error(String.valueOf(obj.get("error")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AjaxResult.success(parsed);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error("回填失败: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ jarvis:
|
|||||||
adhoc-pending-batch-size: 50
|
adhoc-pending-batch-size: 50
|
||||||
# 物流扫描(LogisticsScanTask):轮询 JD 单拉运单 + drain 分享链队列
|
# 物流扫描(LogisticsScanTask):轮询 JD 单拉运单 + drain 分享链队列
|
||||||
scan:
|
scan:
|
||||||
cron: "0 */20 * * * ?"
|
cron: "0 */5 * * * ?"
|
||||||
order-delay-ms: 250
|
order-delay-ms: 250
|
||||||
# 0=不限制;例如 40 可控制单轮最长耗时(余下下轮再扫)
|
# 0=不限制;例如 40 可控制单轮最长耗时(余下下轮再扫)
|
||||||
max-orders-per-round: 0
|
max-orders-per-round: 0
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ jarvis:
|
|||||||
health-path: /health
|
health-path: /health
|
||||||
adhoc-pending-batch-size: 50
|
adhoc-pending-batch-size: 50
|
||||||
scan:
|
scan:
|
||||||
cron: "0 */20 * * * ?"
|
cron: "0 */5 * * * ?"
|
||||||
order-delay-ms: 250
|
order-delay-ms: 250
|
||||||
max-orders-per-round: 0
|
max-orders-per-round: 0
|
||||||
# 获取评论接口服务地址(后端转发)
|
# 获取评论接口服务地址(后端转发)
|
||||||
|
|||||||
@@ -114,6 +114,8 @@ public class SecurityConfig
|
|||||||
requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
|
requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
|
||||||
// 公开接口,允许匿名访问
|
// 公开接口,允许匿名访问
|
||||||
.antMatchers("/public/**").permitAll()
|
.antMatchers("/public/**").permitAll()
|
||||||
|
// 开放页面接口(京东等),允许匿名访问
|
||||||
|
.antMatchers("/open/**").permitAll()
|
||||||
// 腾讯文档OAuth回调接口,允许匿名访问
|
// 腾讯文档OAuth回调接口,允许匿名访问
|
||||||
.antMatchers("/jarvis/tendoc/oauth/callback").permitAll()
|
.antMatchers("/jarvis/tendoc/oauth/callback").permitAll()
|
||||||
// 腾讯文档OAuth回调接口(备用路径),允许匿名访问
|
// 腾讯文档OAuth回调接口(备用路径),允许匿名访问
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.ruoyi.jarvis.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 京东订单商品信息 goods_info
|
||||||
|
*/
|
||||||
|
public class GoodsInfo {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String owner;
|
||||||
|
private String mainSkuId;
|
||||||
|
private String productId;
|
||||||
|
private String imageUrl;
|
||||||
|
private String shopName;
|
||||||
|
private String shopId;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOwner(String owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMainSkuId() {
|
||||||
|
return mainSkuId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMainSkuId(String mainSkuId) {
|
||||||
|
this.mainSkuId = mainSkuId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProductId() {
|
||||||
|
return productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProductId(String productId) {
|
||||||
|
this.productId = productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImageUrl() {
|
||||||
|
return imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImageUrl(String imageUrl) {
|
||||||
|
this.imageUrl = imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShopName() {
|
||||||
|
return shopName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShopName(String shopName) {
|
||||||
|
this.shopName = shopName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShopId() {
|
||||||
|
return shopId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShopId(String shopId) {
|
||||||
|
this.shopId = shopId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package com.ruoyi.jarvis.domain;
|
|||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
import com.ruoyi.common.annotation.Excel;
|
import com.ruoyi.common.annotation.Excel;
|
||||||
import com.ruoyi.common.annotation.Excel.ColumnType;
|
import com.ruoyi.common.annotation.Excel.ColumnType;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.data.annotation.Transient;
|
import org.springframework.data.annotation.Transient;
|
||||||
|
|
||||||
@@ -26,11 +27,15 @@ public class JDOrder extends BaseEntity {
|
|||||||
@Excel(name = "分销标记")
|
@Excel(name = "分销标记")
|
||||||
private String distributionMark;
|
private String distributionMark;
|
||||||
|
|
||||||
/** 型号 */
|
/** 型号(本体,不含店铺后缀) */
|
||||||
@Excel(name = "型号")
|
@Excel(name = "型号")
|
||||||
private String modelNumber;
|
private String modelNumber;
|
||||||
|
|
||||||
/** 列表筛选:型号不含此子串(对应 SQL NOT LIKE %值%),不入库 */
|
/** 型号店铺短前缀(如海尔厨房;完整型号 = modelNumber + modelShop) */
|
||||||
|
@Excel(name = "型号店铺")
|
||||||
|
private String modelShop;
|
||||||
|
|
||||||
|
/** 列表筛选:型号不含这些子串(逗号/空格分隔,对应 SQL 多条 NOT LIKE),不入库 */
|
||||||
@Transient
|
@Transient
|
||||||
private String modelNumberExclude;
|
private String modelNumberExclude;
|
||||||
|
|
||||||
@@ -89,6 +94,10 @@ public class JDOrder extends BaseEntity {
|
|||||||
@Excel(name = "订单状态")
|
@Excel(name = "订单状态")
|
||||||
private Integer orderStatus;
|
private Integer orderStatus;
|
||||||
|
|
||||||
|
/** 发货状态(从 order_rows.express_status 查询,10=待发货) */
|
||||||
|
@Transient
|
||||||
|
private Integer expressStatus;
|
||||||
|
|
||||||
/** 是否参与统计(0否 1是) */
|
/** 是否参与统计(0否 1是) */
|
||||||
@Excel(name = "参与统计")
|
@Excel(name = "参与统计")
|
||||||
private Integer isCountEnabled;
|
private Integer isCountEnabled;
|
||||||
@@ -173,6 +182,11 @@ public class JDOrder extends BaseEntity {
|
|||||||
/** 利润是否手动锁定(1 是:保存时不再自动重算) */
|
/** 利润是否手动锁定(1 是:保存时不再自动重算) */
|
||||||
private Integer profitManual;
|
private Integer profitManual;
|
||||||
|
|
||||||
|
/** 额外成本(计入自动利润:从 netReceipt − 成本中再减去此项,默认 0) */
|
||||||
|
@JsonAlias({ "extra_cost" })
|
||||||
|
@Excel(name = "额外成本")
|
||||||
|
private Double extraCost;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -229,4 +229,8 @@ public class OrderRows extends BaseEntity
|
|||||||
@Excel(name = "订单标签")
|
@Excel(name = "订单标签")
|
||||||
private String orderTag;
|
private String orderTag;
|
||||||
|
|
||||||
|
/** 关联商品信息(goods_info,非表字段) */
|
||||||
|
@Transient
|
||||||
|
private GoodsInfo goodsInfo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
package com.ruoyi.jarvis.domain.dto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跟团查询页订单信息
|
||||||
|
*/
|
||||||
|
public class PromoterOrderInfoVO {
|
||||||
|
|
||||||
|
private String shopName;
|
||||||
|
private String shopLogo;
|
||||||
|
private String orderSource;
|
||||||
|
private String traceTypeStr;
|
||||||
|
private String parentId;
|
||||||
|
private String orderId;
|
||||||
|
private String validCodeMsg;
|
||||||
|
private String skuImageUrl;
|
||||||
|
private String skuId;
|
||||||
|
private String skuName;
|
||||||
|
private String itemId;
|
||||||
|
private Integer skuNum;
|
||||||
|
private String cosPrice;
|
||||||
|
private String orderTime;
|
||||||
|
private String finishTime;
|
||||||
|
/** 价保/赔付金额 */
|
||||||
|
private String proPriceAmount;
|
||||||
|
|
||||||
|
public String getShopName() {
|
||||||
|
return shopName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShopName(String shopName) {
|
||||||
|
this.shopName = shopName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShopLogo() {
|
||||||
|
return shopLogo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShopLogo(String shopLogo) {
|
||||||
|
this.shopLogo = shopLogo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderSource() {
|
||||||
|
return orderSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderSource(String orderSource) {
|
||||||
|
this.orderSource = orderSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTraceTypeStr() {
|
||||||
|
return traceTypeStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTraceTypeStr(String traceTypeStr) {
|
||||||
|
this.traceTypeStr = traceTypeStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParentId() {
|
||||||
|
return parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentId(String parentId) {
|
||||||
|
this.parentId = parentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderId() {
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderId(String orderId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValidCodeMsg() {
|
||||||
|
return validCodeMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidCodeMsg(String validCodeMsg) {
|
||||||
|
this.validCodeMsg = validCodeMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSkuImageUrl() {
|
||||||
|
return skuImageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkuImageUrl(String skuImageUrl) {
|
||||||
|
this.skuImageUrl = skuImageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSkuId() {
|
||||||
|
return skuId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkuId(String skuId) {
|
||||||
|
this.skuId = skuId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSkuName() {
|
||||||
|
return skuName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkuName(String skuName) {
|
||||||
|
this.skuName = skuName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getItemId() {
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItemId(String itemId) {
|
||||||
|
this.itemId = itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSkuNum() {
|
||||||
|
return skuNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkuNum(Integer skuNum) {
|
||||||
|
this.skuNum = skuNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCosPrice() {
|
||||||
|
return cosPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCosPrice(String cosPrice) {
|
||||||
|
this.cosPrice = cosPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOrderTime() {
|
||||||
|
return orderTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrderTime(String orderTime) {
|
||||||
|
this.orderTime = orderTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFinishTime() {
|
||||||
|
return finishTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFinishTime(String finishTime) {
|
||||||
|
this.finishTime = finishTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProPriceAmount() {
|
||||||
|
return proPriceAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProPriceAmount(String proPriceAmount) {
|
||||||
|
this.proPriceAmount = proPriceAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,9 @@ public class QuickRecordModelOption {
|
|||||||
|
|
||||||
private String modelNumber;
|
private String modelNumber;
|
||||||
|
|
||||||
|
/** 型号店铺短前缀 */
|
||||||
|
private String modelShop;
|
||||||
|
|
||||||
/** 最近一次订单的下单付款金额 */
|
/** 最近一次订单的下单付款金额 */
|
||||||
private Double lastPaymentAmount;
|
private Double lastPaymentAmount;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.ruoyi.jarvis.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 快捷录单:型号后缀店铺选项(前缀拼接到型号末尾,如 W5000PLUS2.0白 + 海尔厨房)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class QuickRecordModelShopOption {
|
||||||
|
|
||||||
|
/** 拼接到型号末尾的短前缀,如 海尔官旗 */
|
||||||
|
private String prefix;
|
||||||
|
|
||||||
|
/** 括号内完整店铺名,如 海尔官方旗舰店 */
|
||||||
|
private String fullName;
|
||||||
|
|
||||||
|
/** 展示文案,如 海尔官旗(海尔官方旗舰店) */
|
||||||
|
private String label;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.ruoyi.jarvis.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 闲管家订单:日日顺承运且已关联京东单的出库统计口径(与前台「手动推送/hasPlatformShipped」基本一致)。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class GoofishRrsLogisticsStatsVo {
|
||||||
|
|
||||||
|
/** 已出库:有有效运单去重计数 + 无运单但已发货/完成或本系统发货成功的订单数 */
|
||||||
|
private long shippedOutboundCount;
|
||||||
|
|
||||||
|
/** 待出库:平台「待发货」且无运单、且非本系统发货成功 */
|
||||||
|
private long pendingOutboundCount;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.jarvis.mapper;
|
package com.ruoyi.jarvis.mapper;
|
||||||
|
|
||||||
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||||
|
import com.ruoyi.jarvis.dto.GoofishRrsLogisticsStatsVo;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -25,4 +26,9 @@ public interface ErpGoofishOrderMapper {
|
|||||||
List<ErpGoofishOrder> selectByGoofishOrderNo(@Param("orderNo") String orderNo);
|
List<ErpGoofishOrder> selectByGoofishOrderNo(@Param("orderNo") String orderNo);
|
||||||
|
|
||||||
int resetShipForRetry(@Param("id") Long id);
|
int resetShipForRetry(@Param("id") Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已关联 jd_order_id、承运为日日顺(rrs 或名称含日日顺);排除已退款/已关闭。
|
||||||
|
*/
|
||||||
|
GoofishRrsLogisticsStatsVo selectRrsJdLinkedLogisticsStats();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.ruoyi.jarvis.mapper;
|
||||||
|
|
||||||
|
import com.ruoyi.jarvis.domain.GoodsInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 京东订单商品信息 Mapper
|
||||||
|
*/
|
||||||
|
public interface GoodsInfoMapper {
|
||||||
|
|
||||||
|
GoodsInfo selectGoodsInfoById(Long id);
|
||||||
|
|
||||||
|
List<GoodsInfo> selectGoodsInfoByIds(Long[] ids);
|
||||||
|
}
|
||||||
@@ -67,6 +67,13 @@ public interface JDOrderMapper {
|
|||||||
* 每个型号取其主键最大的一条订单的付款 / 后返(用于快捷录单下拉回填)
|
* 每个型号取其主键最大的一条订单的付款 / 后返(用于快捷录单下拉回填)
|
||||||
*/
|
*/
|
||||||
List<QuickRecordModelOption> selectQuickRecordModelOptions();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -87,4 +87,9 @@ public interface OrderRowsMapper
|
|||||||
* @return 订单列表
|
* @return 订单列表
|
||||||
*/
|
*/
|
||||||
public List<OrderRows> selectOrderRowsByGiftCouponKey(@Param("giftCouponKey") String giftCouponKey);
|
public List<OrderRows> selectOrderRowsByGiftCouponKey(@Param("giftCouponKey") String giftCouponKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据订单号查询(匹配子单号 order_id 或父单号 parent_id)
|
||||||
|
*/
|
||||||
|
public List<OrderRows> selectOrderRowsByOrderNo(@Param("orderNo") String orderNo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
|||||||
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLog;
|
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLog;
|
||||||
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLogQuery;
|
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLogQuery;
|
||||||
import com.ruoyi.jarvis.dto.GoofishShipPreviewVo;
|
import com.ruoyi.jarvis.dto.GoofishShipPreviewVo;
|
||||||
|
import com.ruoyi.jarvis.dto.GoofishRrsLogisticsStatsVo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -17,6 +18,9 @@ public interface IErpGoofishOrderService {
|
|||||||
*/
|
*/
|
||||||
void asyncPipelineAfterNotify(String appid, JSONObject notifyBody);
|
void asyncPipelineAfterNotify(String appid, JSONObject notifyBody);
|
||||||
|
|
||||||
|
/** 日日顺 + 关联京东出库统计(侧边栏):已出库(去重运单口径)/待出库 */
|
||||||
|
GoofishRrsLogisticsStatsVo selectRrsJdLinkedLogisticsStats();
|
||||||
|
|
||||||
List<ErpGoofishOrder> selectList(ErpGoofishOrder query);
|
List<ErpGoofishOrder> selectList(ErpGoofishOrder query);
|
||||||
|
|
||||||
ErpGoofishOrder selectById(Long id);
|
ErpGoofishOrder selectById(Long id);
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.ruoyi.jarvis.service;
|
||||||
|
|
||||||
|
import com.ruoyi.jarvis.domain.GoodsInfo;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 京东订单商品信息 Service
|
||||||
|
*/
|
||||||
|
public interface IGoodsInfoService {
|
||||||
|
|
||||||
|
GoodsInfo selectGoodsInfoById(Long id);
|
||||||
|
|
||||||
|
Map<Long, GoodsInfo> selectGoodsInfoMapByIds(Set<Long> ids);
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -11,8 +11,8 @@ public interface IJDOrderProfitService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据分销标识、型号配置、手动标记等,填充售价(自动时)并计算利润。
|
* 根据分销标识、型号配置、手动标记等,填充售价(自动时)并计算利润。
|
||||||
* F / H-TF:利润 = 对客实收(直款=售价,闲鱼=扣点后的到账)-(下单付款 - 后返金额);
|
* F:利润 = 对客实收(直款=售价,闲鱼=扣点后的到账)-(下单付款 - 后返金额);
|
||||||
* H-TF 未配置型号直款价时回退为固定 15 / 凡- 开头 65。
|
* H-TF:固定利润 15,再扣额外成本。
|
||||||
* 会修改传入的 {@code order}。
|
* 会修改传入的 {@code order}。
|
||||||
*/
|
*/
|
||||||
void recalculate(JDOrder order);
|
void recalculate(JDOrder order);
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ public interface IJDOrderService {
|
|||||||
|
|
||||||
/** 快捷录单:型号及最近一次单的付款 / 后返 */
|
/** 快捷录单:型号及最近一次单的付款 / 后返 */
|
||||||
List<QuickRecordModelOption> selectQuickRecordModelOptions();
|
List<QuickRecordModelOption> selectQuickRecordModelOptions();
|
||||||
|
|
||||||
|
/** 一键迁移:拆分 model_number 末尾店铺前缀到 model_shop */
|
||||||
|
java.util.Map<String, Object> migrateModelShopSplit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -72,4 +72,9 @@ public interface IOrderRowsService
|
|||||||
public int deleteOrderRowsById(String id);
|
public int deleteOrderRowsById(String id);
|
||||||
|
|
||||||
public OrderRows selectOrderRowsByOrderId(String orderId);
|
public OrderRows selectOrderRowsByOrderId(String orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据订单号查询(匹配子单号 order_id 或父单号 parent_id)
|
||||||
|
*/
|
||||||
|
public List<OrderRows> selectOrderRowsByOrderNo(String orderNo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
import com.ruoyi.jarvis.config.JarvisGoofishProperties;
|
import com.ruoyi.jarvis.config.JarvisGoofishProperties;
|
||||||
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||||
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLog;
|
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLog;
|
||||||
|
import com.ruoyi.jarvis.domain.JDOrder;
|
||||||
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLogQuery;
|
import com.ruoyi.jarvis.domain.ErpGoofishOrderEventLogQuery;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
import com.ruoyi.jarvis.dto.GoofishNotifyMessage;
|
import com.ruoyi.jarvis.dto.GoofishNotifyMessage;
|
||||||
|
import com.ruoyi.jarvis.dto.GoofishRrsLogisticsStatsVo;
|
||||||
import com.ruoyi.jarvis.dto.GoofishShipPreviewVo;
|
import com.ruoyi.jarvis.dto.GoofishShipPreviewVo;
|
||||||
import com.ruoyi.jarvis.mapper.ErpGoofishOrderEventLogMapper;
|
import com.ruoyi.jarvis.mapper.ErpGoofishOrderEventLogMapper;
|
||||||
import com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper;
|
import com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper;
|
||||||
@@ -81,6 +84,12 @@ public class ErpGoofishOrderServiceImpl implements IErpGoofishOrderService {
|
|||||||
goofishOrderPipeline.runFullPipeline(appid, notifyBody);
|
goofishOrderPipeline.runFullPipeline(appid, notifyBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GoofishRrsLogisticsStatsVo selectRrsJdLinkedLogisticsStats() {
|
||||||
|
GoofishRrsLogisticsStatsVo vo = erpGoofishOrderMapper.selectRrsJdLinkedLogisticsStats();
|
||||||
|
return vo != null ? vo : new GoofishRrsLogisticsStatsVo();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ErpGoofishOrder> selectList(ErpGoofishOrder query) {
|
public List<ErpGoofishOrder> selectList(ErpGoofishOrder query) {
|
||||||
return erpGoofishOrderMapper.selectList(query);
|
return erpGoofishOrderMapper.selectList(query);
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.ruoyi.jarvis.service.impl;
|
||||||
|
|
||||||
|
import com.ruoyi.jarvis.domain.GoodsInfo;
|
||||||
|
import com.ruoyi.jarvis.mapper.GoodsInfoMapper;
|
||||||
|
import com.ruoyi.jarvis.service.IGoodsInfoService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class GoodsInfoServiceImpl implements IGoodsInfoService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private GoodsInfoMapper goodsInfoMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GoodsInfo selectGoodsInfoById(Long id) {
|
||||||
|
if (id == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return goodsInfoMapper.selectGoodsInfoById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Long, GoodsInfo> selectGoodsInfoMapByIds(Set<Long> ids) {
|
||||||
|
if (ids == null || ids.isEmpty()) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
List<GoodsInfo> list = goodsInfoMapper.selectGoodsInfoByIds(ids.toArray(new Long[0]));
|
||||||
|
Map<Long, GoodsInfo> map = new HashMap<>();
|
||||||
|
if (list != null) {
|
||||||
|
for (GoodsInfo goodsInfo : list) {
|
||||||
|
if (goodsInfo != null && goodsInfo.getId() != null) {
|
||||||
|
map.put(goodsInfo.getId(), goodsInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import com.ruoyi.jarvis.domain.WeComShareLinkLogisticsJob;
|
|||||||
import com.ruoyi.jarvis.service.IInstructionService;
|
import com.ruoyi.jarvis.service.IInstructionService;
|
||||||
import com.ruoyi.jarvis.service.IOrderRowsService;
|
import com.ruoyi.jarvis.service.IOrderRowsService;
|
||||||
import com.ruoyi.jarvis.service.IJDOrderService;
|
import com.ruoyi.jarvis.service.IJDOrderService;
|
||||||
|
import com.ruoyi.jarvis.service.IJDOrderModelShopService;
|
||||||
import com.ruoyi.jarvis.service.IProductJdConfigService;
|
import com.ruoyi.jarvis.service.IProductJdConfigService;
|
||||||
import com.ruoyi.jarvis.service.IPhoneReplaceConfigService;
|
import com.ruoyi.jarvis.service.IPhoneReplaceConfigService;
|
||||||
import com.ruoyi.jarvis.service.SuperAdminService;
|
import com.ruoyi.jarvis.service.SuperAdminService;
|
||||||
@@ -42,6 +43,8 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
@Resource
|
@Resource
|
||||||
private IJDOrderService jdOrderService;
|
private IJDOrderService jdOrderService;
|
||||||
@Resource
|
@Resource
|
||||||
|
private IJDOrderModelShopService jdOrderModelShopService;
|
||||||
|
@Resource
|
||||||
private SuperAdminService superAdminService;
|
private SuperAdminService superAdminService;
|
||||||
@Resource
|
@Resource
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
@@ -358,13 +361,13 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
// 统一截取分销标记
|
// 统一截取分销标记
|
||||||
list.forEach(order -> order.setDistributionMark(truncateDistributionMark(order.getDistributionMark())));
|
list.forEach(order -> order.setDistributionMark(truncateDistributionMark(order.getDistributionMark())));
|
||||||
String low = kw.toLowerCase(Locale.ROOT);
|
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("未找到匹配的订单");
|
if (matched.isEmpty()) return Collections.singletonList("未找到匹配的订单");
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (JDOrder o : matched) {
|
for (JDOrder o : matched) {
|
||||||
i++;
|
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());
|
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());
|
List<JDOrder> sorted = filtered.stream().sorted(Comparator.comparing(JDOrder::getRemark, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (JDOrder o : sorted) {
|
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());
|
return Collections.singletonList(sb.toString());
|
||||||
}
|
}
|
||||||
@@ -422,7 +425,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
String dm = e.getKey() != null ? e.getKey() : "未提供";
|
String dm = e.getKey() != null ? e.getKey() : "未提供";
|
||||||
List<JDOrder> orders = e.getValue();
|
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;
|
int totalCount = 0;
|
||||||
StringBuilder summary = new StringBuilder();
|
StringBuilder summary = new StringBuilder();
|
||||||
@@ -445,7 +448,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
|
|
||||||
// 找到该型号价格最高的订单
|
// 找到该型号价格最高的订单
|
||||||
for (JDOrder order : orders) {
|
for (JDOrder order : orders) {
|
||||||
if (model.equals(order.getModelNumber())) {
|
if (model.equals(orderFullModel(order))) {
|
||||||
JDOrder currentMax = groupMaxPriceOrders.get(model);
|
JDOrder currentMax = groupMaxPriceOrders.get(model);
|
||||||
if (currentMax == null ||
|
if (currentMax == null ||
|
||||||
(order.getPaymentAmount() != 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.getRemark() != null ? o.getRemark() : "未提供").append("\n")
|
||||||
.append("备注:").append(o.getStatus() != null ? o.getStatus() : " ").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.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("地址:").append(o.getAddress() != null ? o.getAddress() : "未提供").append("\n")
|
||||||
.append("物流链接:\n").append(o.getLogisticsLink() != null ? o.getLogisticsLink() : "无");
|
.append("物流链接:\n").append(o.getLogisticsLink() != null ? o.getLogisticsLink() : "无");
|
||||||
}
|
}
|
||||||
@@ -594,7 +597,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
List<JDOrder> orders = e.getValue();
|
List<JDOrder> orders = e.getValue();
|
||||||
|
|
||||||
Map<String, Long> byModel = orders.stream()
|
Map<String, Long> byModel = orders.stream()
|
||||||
.collect(Collectors.groupingBy(JDOrder::getModelNumber, Collectors.counting()));
|
.collect(Collectors.groupingBy(this::orderFullModel, Collectors.counting()));
|
||||||
|
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
StringBuilder summary = new StringBuilder();
|
StringBuilder summary = new StringBuilder();
|
||||||
@@ -616,7 +619,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
|
|
||||||
// 找到该型号价格最高的订单
|
// 找到该型号价格最高的订单
|
||||||
for (JDOrder order : orders) {
|
for (JDOrder order : orders) {
|
||||||
if (model.equals(order.getModelNumber())) {
|
if (model.equals(orderFullModel(order))) {
|
||||||
JDOrder currentMax = buyerMaxPriceOrders.get(model);
|
JDOrder currentMax = buyerMaxPriceOrders.get(model);
|
||||||
if (currentMax == null ||
|
if (currentMax == null ||
|
||||||
(order.getPaymentAmount() != 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.getRemark() != null ? o.getRemark() : "未提供").append("\n")
|
||||||
.append("备注:").append(o.getStatus() != null ? o.getStatus() : " ").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.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("地址:").append(o.getAddress() != null ? o.getAddress() : "未提供").append("\n")
|
||||||
.append("物流链接:\n").append(o.getLogisticsLink() != null ? o.getLogisticsLink() : "无");
|
.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();
|
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);
|
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 rawModelToken = extractLastNonChineseToken(addressLine);
|
||||||
String modelNumber = sanitizeModel(rawModelToken);
|
String modelNumber = sanitizeModel(rawModelToken);
|
||||||
|
String lookupModel = jdOrderModelShopService.lookupModelBase(modelNumber);
|
||||||
String cleanedAddress = addressLine.replaceAll("\\[.*?]", "").replace(rawModelToken, "").replaceAll("\\s+", " ").trim();
|
String cleanedAddress = addressLine.replaceAll("\\[.*?]", "").replace(rawModelToken, "").replaceAll("\\s+", " ").trim();
|
||||||
String fullAddress = cleanedAddress + " 安装派送联系" + phone + (suffix.isEmpty() ? "" : "转" + suffix);
|
String fullAddress = cleanedAddress + " 安装派送联系" + phone + (suffix.isEmpty() ? "" : "转" + suffix);
|
||||||
|
|
||||||
String jfLink = productJdConfigService.getJdUrlByProductModel(modelNumber);
|
String jfLink = productJdConfigService.getJdUrlByProductModel(lookupModel);
|
||||||
|
|
||||||
StringBuilder sheng = new StringBuilder();
|
StringBuilder sheng = new StringBuilder();
|
||||||
sheng.append("生\n").append(distributionMark).append("\n").append(modelNumber).append("\n").append(jfLink != null ? jfLink : "").append("\n")
|
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 distributionMark = split[1];
|
||||||
String link = sanitizeLink(split[3]);
|
String link = sanitizeLink(split[3]);
|
||||||
if ((link == null || link.isEmpty()) && shouldAutoFillLink(distributionMark)) {
|
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()) {
|
if (fetched != null && !fetched.isEmpty()) {
|
||||||
link = fetched;
|
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();
|
StringBuilder sheng = new StringBuilder();
|
||||||
@@ -1453,7 +1457,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
if (order == null) {
|
if (order == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String model = order.getModelNumber();
|
String model = jdOrderModelShopService.fullModel(order);
|
||||||
String address = order.getAddress();
|
String address = order.getAddress();
|
||||||
String logistics = extractOriginalLogisticsLinkNew(originalInput);
|
String logistics = extractOriginalLogisticsLinkNew(originalInput);
|
||||||
if (logistics == null && order.getLogisticsLink() != null) {
|
if (logistics == null && order.getLogisticsLink() != null) {
|
||||||
@@ -1515,6 +1519,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
String originalInput = input.trim().replace("元", "");
|
String originalInput = input.trim().replace("元", "");
|
||||||
// 与 JDUtil.parseOrderFromText 一致的模板字段
|
// 与 JDUtil.parseOrderFromText 一致的模板字段
|
||||||
JDOrder order = parseOrderFromText(originalInput);
|
JDOrder order = parseOrderFromText(originalInput);
|
||||||
|
jdOrderModelShopService.normalizeOrder(order);
|
||||||
|
|
||||||
// 字段校验并返回缺失项(根据新模板格式,单号存储在remark字段中)
|
// 字段校验并返回缺失项(根据新模板格式,单号存储在remark字段中)
|
||||||
StringBuilder missing = new StringBuilder();
|
StringBuilder missing = new StringBuilder();
|
||||||
@@ -1658,7 +1663,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
sb.append("第三方单号:").append(order.getThirdPartyOrderNo().trim()).append("\n");
|
sb.append("第三方单号:").append(order.getThirdPartyOrderNo().trim()).append("\n");
|
||||||
}
|
}
|
||||||
sb.append("分销标记:").append(nvl(order.getDistributionMark())).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(nvl(order.getBuyer())).append("\n");
|
||||||
sb.append("付款:").append(order.getPaymentAmount() != null ? order.getPaymentAmount().toString() : "").append("\n");
|
sb.append("付款:").append(order.getPaymentAmount() != null ? order.getPaymentAmount().toString() : "").append("\n");
|
||||||
sb.append("后返:").append(order.getRebateAmount() != null ? order.getRebateAmount().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;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 对外展示 / 录单文案用的完整型号(本体 + 店铺前缀) */
|
||||||
|
private String orderFullModel(JDOrder order) {
|
||||||
|
return order == null ? "" : jdOrderModelShopService.fullModel(order);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isEmpty(String s) {
|
private boolean isEmpty(String s) {
|
||||||
return s == null || s.isEmpty();
|
return s == null || s.isEmpty();
|
||||||
}
|
}
|
||||||
@@ -1730,7 +1740,7 @@ public class InstructionServiceImpl implements IInstructionService {
|
|||||||
sb.append("下单地址(注意带分机):\n");
|
sb.append("下单地址(注意带分机):\n");
|
||||||
sb.append(order.getAddress() != null ? order.getAddress() : "").append("\n");
|
sb.append(order.getAddress() != null ? order.getAddress() : "").append("\n");
|
||||||
sb.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("下单人(需填):\n");
|
sb.append("下单人(需填):\n");
|
||||||
sb.append(order.getBuyer() != null ? order.getBuyer() : "").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.getDistributionMark() != null ? order.getDistributionMark() : "").append("\n");
|
||||||
sb.append("第三方单号:").append(order.getThirdPartyOrderNo() != null ? order.getThirdPartyOrderNo() : "").append("\n");
|
sb.append("第三方单号:").append(order.getThirdPartyOrderNo() != null ? order.getThirdPartyOrderNo() : "").append("\n");
|
||||||
sb.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("链接:\n");
|
||||||
sb.append(order.getLink() != null ? order.getLink() : "").append("\n");
|
sb.append(order.getLink() != null ? order.getLink() : "").append("\n");
|
||||||
sb.append("下单付款:\n");
|
sb.append("下单付款:\n");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,39 +46,25 @@ public class JDOrderProfitServiceImpl implements IJDOrderProfitService {
|
|||||||
|
|
||||||
if ("H-TF".equals(mark)) {
|
if ("H-TF".equals(mark)) {
|
||||||
if (!profitLocked) {
|
if (!profitLocked) {
|
||||||
// 与 F 单一致:利润 = 对客实收 − (下单付款 − 后返)。列表未填售价时默认直款并从型号配置取价。
|
// H-TF 固定利润 15,再扣额外成本(不走 F 单售价公式)
|
||||||
String type = order.getSellingPriceType();
|
order.setProfit(BigDecimal.valueOf(15.0 - extraCostOrZero(order))
|
||||||
if (type == null || type.isEmpty()) {
|
.setScale(2, RoundingMode.HALF_UP).doubleValue());
|
||||||
order.setSellingPriceType("direct");
|
|
||||||
}
|
|
||||||
if (!sellingLocked && order.getSellingPrice() == null) {
|
|
||||||
fillSellingPriceFromConfig(order);
|
|
||||||
}
|
|
||||||
String effType = order.getSellingPriceType();
|
|
||||||
Double sp = order.getSellingPrice();
|
|
||||||
if (effType != null && !effType.isEmpty() && sp != null) {
|
|
||||||
computeProfitForF(order);
|
|
||||||
} else {
|
|
||||||
String buyer = order.getBuyer();
|
|
||||||
boolean fan = buyer != null && buyer.trim().startsWith("凡-");
|
|
||||||
order.setProfit(fan ? 65.0 : 15.0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("F".equals(mark) || mark.startsWith("F-")) {
|
// 其余分销标记:与 F / F-* / PDD / H / … 共用同一利润公式(含额外成本);须有售价渠道 + 售价才自动算出利润,否则清空
|
||||||
if (!sellingLocked) {
|
if (!sellingLocked) {
|
||||||
fillSellingPriceFromConfig(order);
|
fillSellingPriceFromConfig(order);
|
||||||
}
|
|
||||||
if (!profitLocked) {
|
|
||||||
computeProfitForF(order);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!profitLocked) {
|
if (!profitLocked) {
|
||||||
order.setProfit(null);
|
String type = order.getSellingPriceType();
|
||||||
|
Double sp = order.getSellingPrice();
|
||||||
|
if (type != null && !type.trim().isEmpty() && sp != null) {
|
||||||
|
computeProfitForF(order);
|
||||||
|
} else {
|
||||||
|
order.setProfit(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,13 +113,19 @@ public class JDOrderProfitServiceImpl implements IJDOrderProfitService {
|
|||||||
order.setProfit(null);
|
order.setProfit(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 成本 = 下单付款 - 后返金额;利润 = 对客实收(直款=售价,闲鱼=扣点后的到账)- 成本
|
// 成本 = 下单付款 - 后返金额;利润 = 对客实收 − 成本 − 额外成本
|
||||||
double cost = BigDecimal.valueOf(pay).subtract(BigDecimal.valueOf(rebate))
|
double cost = BigDecimal.valueOf(pay).subtract(BigDecimal.valueOf(rebate))
|
||||||
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
.setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||||
order.setProfit(BigDecimal.valueOf(netReceipt - cost)
|
double net = netReceipt - cost - extraCostOrZero(order);
|
||||||
|
order.setProfit(BigDecimal.valueOf(net)
|
||||||
.setScale(2, RoundingMode.HALF_UP).doubleValue());
|
.setScale(2, RoundingMode.HALF_UP).doubleValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static double extraCostOrZero(JDOrder order) {
|
||||||
|
Double e = order == null ? null : order.getExtraCost();
|
||||||
|
return e != null ? e : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int syncAutoProfitIfChanged(List<Long> ids) {
|
public int syncAutoProfitIfChanged(List<Long> ids) {
|
||||||
if (ids == null || ids.isEmpty()) {
|
if (ids == null || ids.isEmpty()) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.ruoyi.jarvis.service.impl;
|
|||||||
import com.ruoyi.jarvis.domain.JDOrder;
|
import com.ruoyi.jarvis.domain.JDOrder;
|
||||||
import com.ruoyi.jarvis.domain.dto.QuickRecordModelOption;
|
import com.ruoyi.jarvis.domain.dto.QuickRecordModelOption;
|
||||||
import com.ruoyi.jarvis.mapper.JDOrderMapper;
|
import com.ruoyi.jarvis.mapper.JDOrderMapper;
|
||||||
|
import com.ruoyi.jarvis.service.IJDOrderModelShopService;
|
||||||
import com.ruoyi.jarvis.service.IJDOrderProfitService;
|
import com.ruoyi.jarvis.service.IJDOrderProfitService;
|
||||||
import com.ruoyi.jarvis.service.IJDOrderService;
|
import com.ruoyi.jarvis.service.IJDOrderService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -19,6 +20,9 @@ public class JDOrderServiceImpl implements IJDOrderService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IJDOrderProfitService jdOrderProfitService;
|
private IJDOrderProfitService jdOrderProfitService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IJDOrderModelShopService jdOrderModelShopService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<JDOrder> selectJDOrderList(JDOrder jdOrder) {
|
public List<JDOrder> selectJDOrderList(JDOrder jdOrder) {
|
||||||
return jdOrderMapper.selectJDOrderList(jdOrder);
|
return jdOrderMapper.selectJDOrderList(jdOrder);
|
||||||
@@ -36,12 +40,14 @@ public class JDOrderServiceImpl implements IJDOrderService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int insertJDOrder(JDOrder jdOrder) {
|
public int insertJDOrder(JDOrder jdOrder) {
|
||||||
|
jdOrderModelShopService.normalizeOrder(jdOrder);
|
||||||
jdOrderProfitService.recalculate(jdOrder);
|
jdOrderProfitService.recalculate(jdOrder);
|
||||||
return jdOrderMapper.insertJDOrder(jdOrder);
|
return jdOrderMapper.insertJDOrder(jdOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int updateJDOrder(JDOrder jdOrder) {
|
public int updateJDOrder(JDOrder jdOrder) {
|
||||||
|
jdOrderModelShopService.normalizeOrder(jdOrder);
|
||||||
return jdOrderMapper.updateJDOrder(jdOrder);
|
return jdOrderMapper.updateJDOrder(jdOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +93,11 @@ public class JDOrderServiceImpl implements IJDOrderService {
|
|||||||
public List<QuickRecordModelOption> selectQuickRecordModelOptions() {
|
public List<QuickRecordModelOption> selectQuickRecordModelOptions() {
|
||||||
return jdOrderMapper.selectQuickRecordModelOptions();
|
return jdOrderMapper.selectQuickRecordModelOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.util.Map<String, Object> migrateModelShopSplit() {
|
||||||
|
return jdOrderModelShopService.migrateExistingOrders();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -63,13 +63,13 @@ public class OpenPhoneForwardService {
|
|||||||
private static final String BOT_OPEN = "AJL05_bot";
|
private static final String BOT_OPEN = "AJL05_bot";
|
||||||
|
|
||||||
/** 「慢开」→ 对应 Bot 用户名 */
|
/** 「慢开」→ 对应 Bot 用户名 */
|
||||||
private static final String BOT_SLOW_OPEN = "QingBaoJuZQbot";
|
private static final String BOT_SLOW_OPEN = "QingBaoZhuQuebot";
|
||||||
|
|
||||||
private static final int REPLY_TAKE_NTH_OPEN_BOT = 2;
|
private static final int REPLY_TAKE_NTH_OPEN_BOT = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 情报局推广条:Telegram 常为 Markdown
|
* 情报局推广条:Telegram 常为 Markdown
|
||||||
* {@code **👉**[**文案**](url)**👈**};另保留旧版纯文本。
|
* {@code **👉**[**文案**](url)**👈**}、{@code 👉[文案](url)👈};另保留旧版纯文本。
|
||||||
*/
|
*/
|
||||||
private static final Pattern[] QINGBAO_REPLY_JUNK_PATTERNS = {
|
private static final Pattern[] QINGBAO_REPLY_JUNK_PATTERNS = {
|
||||||
Pattern.compile(
|
Pattern.compile(
|
||||||
@@ -78,6 +78,12 @@ public class OpenPhoneForwardService {
|
|||||||
Pattern.compile(
|
Pattern.compile(
|
||||||
"\\*\\*👉\u200D?\\*\\*\\[\\*\\*如机器人提示被注销点我防丢\\*\\*\\]"
|
"\\*\\*👉\u200D?\\*\\*\\[\\*\\*如机器人提示被注销点我防丢\\*\\*\\]"
|
||||||
+ "\\(https?://telegra\\.ph/qingbaoju-10-01\\)\\*\\*👈\\*\\*"),
|
+ "\\(https?://telegra\\.ph/qingbaoju-10-01\\)\\*\\*👈\\*\\*"),
|
||||||
|
Pattern.compile(
|
||||||
|
"\uD83D\uDC49\u200D?\\[公安路线查询价格表\\]"
|
||||||
|
+ "\\(https?://t\\.me/\\+C20ADPmEKJU0ZGFl\\)\uD83D\uDC48"),
|
||||||
|
Pattern.compile(
|
||||||
|
"\uD83D\uDC49\u200D?\\[如机器人提示被注销点我防丢\\]"
|
||||||
|
+ "\\(https?://telegra\\.ph/qingbaoju-10-01\\)\uD83D\uDC48"),
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] QINGBAO_REPLY_JUNK_LITERAL = {
|
private static final String[] QINGBAO_REPLY_JUNK_LITERAL = {
|
||||||
@@ -85,6 +91,10 @@ public class OpenPhoneForwardService {
|
|||||||
"\uD83D\uDC49\u200D如机器人提示被注销点我防丢 (https://telegra.ph/qingbaoju-10-01)\uD83D\uDC48",
|
"\uD83D\uDC49\u200D如机器人提示被注销点我防丢 (https://telegra.ph/qingbaoju-10-01)\uD83D\uDC48",
|
||||||
"\uD83D\uDC49公安路线查询价格表 (https://t.me/+C20ADPmEKJU0ZGFl)\uD83D\uDC48",
|
"\uD83D\uDC49公安路线查询价格表 (https://t.me/+C20ADPmEKJU0ZGFl)\uD83D\uDC48",
|
||||||
"\uD83D\uDC49如机器人提示被注销点我防丢 (https://telegra.ph/qingbaoju-10-01)\uD83D\uDC48",
|
"\uD83D\uDC49如机器人提示被注销点我防丢 (https://telegra.ph/qingbaoju-10-01)\uD83D\uDC48",
|
||||||
|
"\uD83D\uDC49\u200D[公安路线查询价格表](https://t.me/+C20ADPmEKJU0ZGFl)\uD83D\uDC48",
|
||||||
|
"\uD83D\uDC49\u200D[如机器人提示被注销点我防丢](https://telegra.ph/qingbaoju-10-01)\uD83D\uDC48",
|
||||||
|
"\uD83D\uDC49[公安路线查询价格表](https://t.me/+C20ADPmEKJU0ZGFl)\uD83D\uDC48",
|
||||||
|
"\uD83D\uDC49[如机器人提示被注销点我防丢](https://telegra.ph/qingbaoju-10-01)\uD83D\uDC48",
|
||||||
};
|
};
|
||||||
|
|
||||||
@Value("${jarvis.phone-forward.enabled:false}")
|
@Value("${jarvis.phone-forward.enabled:false}")
|
||||||
|
|||||||
@@ -112,4 +112,9 @@ public class OrderRowsServiceImpl implements IOrderRowsService
|
|||||||
public OrderRows selectOrderRowsByOrderId(String orderId) {
|
public OrderRows selectOrderRowsByOrderId(String orderId) {
|
||||||
return orderRowsMapper.selectOrderRowsByOrderId(orderId);
|
return orderRowsMapper.selectOrderRowsByOrderId(orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<OrderRows> selectOrderRowsByOrderNo(String orderNo) {
|
||||||
|
return orderRowsMapper.selectOrderRowsByOrderNo(orderNo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1021,7 +1021,7 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
|||||||
|
|
||||||
// 标题行
|
// 标题行
|
||||||
StringBuilder daixiadanBuilder = new StringBuilder();
|
StringBuilder daixiadanBuilder = new StringBuilder();
|
||||||
daixiadanBuilder.append("(一键代下) ").append(cleanTitle).append("\n");
|
daixiadanBuilder.append(cleanTitle).append("\n");
|
||||||
// 型号行(可选)
|
// 型号行(可选)
|
||||||
if (StringUtils.isNotEmpty(cleanRemark)) {
|
if (StringUtils.isNotEmpty(cleanRemark)) {
|
||||||
daixiadanBuilder.append("型号:").append(cleanRemark).append("\n");
|
daixiadanBuilder.append("型号:").append(cleanRemark).append("\n");
|
||||||
@@ -1030,11 +1030,10 @@ public class SocialMediaServiceImpl implements ISocialMediaService
|
|||||||
|
|
||||||
// 教你下单版
|
// 教你下单版
|
||||||
StringBuilder jiaonixiadanBuilder = new StringBuilder();
|
StringBuilder jiaonixiadanBuilder = new StringBuilder();
|
||||||
jiaonixiadanBuilder.append("【教你下单】 ").append(cleanTitle).append("\n");
|
jiaonixiadanBuilder.append(cleanTitle).append("\n");
|
||||||
if (StringUtils.isNotEmpty(cleanRemark)) {
|
if (StringUtils.isNotEmpty(cleanRemark)) {
|
||||||
jiaonixiadanBuilder.append("型号:").append(cleanRemark).append("\n");
|
jiaonixiadanBuilder.append("型号:").append(cleanRemark).append("\n");
|
||||||
}
|
}
|
||||||
jiaonixiadanBuilder.append(wenanBase).append("\n\n");
|
|
||||||
|
|
||||||
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
|
||||||
String dateStr = sdf.format(new java.util.Date());
|
String dateStr = sdf.format(new java.util.Date());
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 物流信息扫描定时任务
|
* 物流信息扫描定时任务
|
||||||
* 按配置周期(默认每 20 分钟)扫描分销标记为 F/PDD 等的订单(最近 30 天),拉物流并推送;
|
* 按配置周期(默认每 5 分钟)扫描分销标记为 F/PDD 等的订单(最近 30 天),拉物流并推送;
|
||||||
* 结束后处理企微分享链 adhoc 队列。
|
* 结束后处理企微分享链 adhoc 队列。
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@@ -39,7 +39,7 @@ public class LogisticsScanTask {
|
|||||||
/**
|
/**
|
||||||
* 只扫描最近 30 天的订单(SQL 固定);周期与单轮上限见 jarvis.server.logistics.scan.*
|
* 只扫描最近 30 天的订单(SQL 固定);周期与单轮上限见 jarvis.server.logistics.scan.*
|
||||||
*/
|
*/
|
||||||
@Scheduled(cron = "${jarvis.server.logistics.scan.cron:0 */20 * * * ?}")
|
@Scheduled(cron = "${jarvis.server.logistics.scan.cron:0 */5 * * * ?}")
|
||||||
public void scanAndFetchLogistics() {
|
public void scanAndFetchLogistics() {
|
||||||
long t0 = System.currentTimeMillis();
|
long t0 = System.currentTimeMillis();
|
||||||
int orderCandidates = 0;
|
int orderCandidates = 0;
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
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;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析快捷录单型号店铺配置:每行/逗号分隔,格式「短前缀(完整店名)」。
|
||||||
|
*/
|
||||||
|
public final class QuickRecordModelShopOptionUtil {
|
||||||
|
|
||||||
|
public static final String CONFIG_KEY = "quickRecord.modelShopOptions";
|
||||||
|
|
||||||
|
private static final Pattern LINE_PATTERN = Pattern.compile("^(.+?)[((](.+)[))]$");
|
||||||
|
|
||||||
|
private QuickRecordModelShopOptionUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<QuickRecordModelShopOption> parseOptions(String raw) {
|
||||||
|
if (StringUtils.isEmpty(raw)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
String[] parts = raw.split("[\\r\\n,,]+");
|
||||||
|
List<QuickRecordModelShopOption> list = new ArrayList<>();
|
||||||
|
for (String part : parts) {
|
||||||
|
if (StringUtils.isEmpty(part)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QuickRecordModelShopOption opt = parseOneLine(part.trim());
|
||||||
|
if (opt != null && StringUtils.isNotEmpty(opt.getPrefix())) {
|
||||||
|
list.add(opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static QuickRecordModelShopOption parseOneLine(String line) {
|
||||||
|
if (StringUtils.isEmpty(line)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Matcher m = LINE_PATTERN.matcher(line);
|
||||||
|
QuickRecordModelShopOption opt = new QuickRecordModelShopOption();
|
||||||
|
if (m.matches()) {
|
||||||
|
opt.setPrefix(m.group(1).trim());
|
||||||
|
opt.setFullName(m.group(2).trim());
|
||||||
|
} else {
|
||||||
|
opt.setPrefix(line.trim());
|
||||||
|
opt.setFullName("");
|
||||||
|
}
|
||||||
|
opt.setLabel(buildLabel(opt.getPrefix(), opt.getFullName()));
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildLabel(String prefix, String fullName) {
|
||||||
|
if (StringUtils.isEmpty(fullName)) {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
return prefix + "(" + fullName + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从完整型号末尾匹配已知店铺前缀(长前缀优先),用于回显拆分。
|
||||||
|
*/
|
||||||
|
public static String[] splitModelSuffix(String fullModel, List<QuickRecordModelShopOption> options) {
|
||||||
|
String full = StringUtils.trim(fullModel);
|
||||||
|
if (StringUtils.isEmpty(full) || options == null || options.isEmpty()) {
|
||||||
|
return new String[] { full, "" };
|
||||||
|
}
|
||||||
|
List<QuickRecordModelShopOption> sorted = new ArrayList<>(options);
|
||||||
|
sorted.sort((a, b) -> {
|
||||||
|
int la = a.getPrefix() != null ? a.getPrefix().length() : 0;
|
||||||
|
int lb = b.getPrefix() != null ? b.getPrefix().length() : 0;
|
||||||
|
return Integer.compare(lb, la);
|
||||||
|
});
|
||||||
|
for (QuickRecordModelShopOption opt : sorted) {
|
||||||
|
String prefix = opt.getPrefix();
|
||||||
|
if (StringUtils.isEmpty(prefix)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (full.endsWith(prefix) && full.length() > prefix.length()) {
|
||||||
|
return new String[] { full.substring(0, full.length() - prefix.length()), prefix };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -182,4 +182,65 @@
|
|||||||
update_time = now()
|
update_time = now()
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<!-- 日日顺 + 已关联京东:已出库/待出库口径与 erpGoofishOrder 列表「手动推送」一致(有单号或已发货状态) -->
|
||||||
|
<select id="selectRrsJdLinkedLogisticsStats"
|
||||||
|
resultType="com.ruoyi.jarvis.dto.GoofishRrsLogisticsStatsVo">
|
||||||
|
SELECT
|
||||||
|
(
|
||||||
|
IFNULL(COUNT(DISTINCT CASE
|
||||||
|
WHEN e.jd_order_id IS NOT NULL
|
||||||
|
AND (
|
||||||
|
LOWER(TRIM(IFNULL(e.detail_express_code, ''))) = 'rrs'
|
||||||
|
OR LOWER(TRIM(IFNULL(e.ship_express_code, ''))) = 'rrs'
|
||||||
|
OR IFNULL(e.detail_express_name, '') LIKE CONCAT('%', '日日顺', '%')
|
||||||
|
)
|
||||||
|
AND (e.order_status IS NULL OR e.order_status NOT IN (23, 24))
|
||||||
|
AND (
|
||||||
|
LENGTH(TRIM(IFNULL(e.local_waybill_no, ''))) > 0
|
||||||
|
OR LENGTH(TRIM(IFNULL(e.detail_waybill_no, ''))) > 0
|
||||||
|
)
|
||||||
|
THEN CASE
|
||||||
|
WHEN LENGTH(TRIM(IFNULL(e.local_waybill_no, ''))) > 0
|
||||||
|
THEN TRIM(e.local_waybill_no)
|
||||||
|
ELSE TRIM(e.detail_waybill_no)
|
||||||
|
END
|
||||||
|
ELSE NULL
|
||||||
|
END), 0)
|
||||||
|
+
|
||||||
|
IFNULL(COUNT(CASE
|
||||||
|
WHEN e.jd_order_id IS NOT NULL
|
||||||
|
AND (
|
||||||
|
LOWER(TRIM(IFNULL(e.detail_express_code, ''))) = 'rrs'
|
||||||
|
OR LOWER(TRIM(IFNULL(e.ship_express_code, ''))) = 'rrs'
|
||||||
|
OR IFNULL(e.detail_express_name, '') LIKE CONCAT('%', '日日顺', '%')
|
||||||
|
)
|
||||||
|
AND (e.order_status IS NULL OR e.order_status NOT IN (23, 24))
|
||||||
|
AND LENGTH(TRIM(IFNULL(e.local_waybill_no, ''))) = 0
|
||||||
|
AND LENGTH(TRIM(IFNULL(e.detail_waybill_no, ''))) = 0
|
||||||
|
AND (
|
||||||
|
IFNULL(e.ship_status, 0) = 1
|
||||||
|
OR IFNULL(e.order_status, 0) IN (21, 22)
|
||||||
|
)
|
||||||
|
THEN 1
|
||||||
|
ELSE NULL
|
||||||
|
END), 0)
|
||||||
|
) AS shippedOutboundCount,
|
||||||
|
IFNULL(COUNT(CASE
|
||||||
|
WHEN e.jd_order_id IS NOT NULL
|
||||||
|
AND (
|
||||||
|
LOWER(TRIM(IFNULL(e.detail_express_code, ''))) = 'rrs'
|
||||||
|
OR LOWER(TRIM(IFNULL(e.ship_express_code, ''))) = 'rrs'
|
||||||
|
OR IFNULL(e.detail_express_name, '') LIKE CONCAT('%', '日日顺', '%')
|
||||||
|
)
|
||||||
|
AND (e.order_status IS NULL OR e.order_status NOT IN (23, 24))
|
||||||
|
AND IFNULL(e.order_status, 0) = 12
|
||||||
|
AND LENGTH(TRIM(IFNULL(e.local_waybill_no, ''))) = 0
|
||||||
|
AND LENGTH(TRIM(IFNULL(e.detail_waybill_no, ''))) = 0
|
||||||
|
AND (e.ship_status IS NULL OR e.ship_status != 1)
|
||||||
|
THEN 1
|
||||||
|
ELSE NULL
|
||||||
|
END), 0) AS pendingOutboundCount
|
||||||
|
FROM erp_goofish_order e
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ruoyi.jarvis.mapper.GoodsInfoMapper">
|
||||||
|
|
||||||
|
<resultMap type="GoodsInfo" id="GoodsInfoResult">
|
||||||
|
<result property="id" column="id"/>
|
||||||
|
<result property="owner" column="owner"/>
|
||||||
|
<result property="mainSkuId" column="main_sku_id"/>
|
||||||
|
<result property="productId" column="product_id"/>
|
||||||
|
<result property="imageUrl" column="image_url"/>
|
||||||
|
<result property="shopName" column="shop_name"/>
|
||||||
|
<result property="shopId" column="shop_id"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectGoodsInfoVo">
|
||||||
|
select id, owner, main_sku_id, product_id, image_url, shop_name, shop_id from goods_info
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectGoodsInfoById" parameterType="Long" resultMap="GoodsInfoResult">
|
||||||
|
<include refid="selectGoodsInfoVo"/>
|
||||||
|
where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectGoodsInfoByIds" resultMap="GoodsInfoResult">
|
||||||
|
<include refid="selectGoodsInfoVo"/>
|
||||||
|
where id in
|
||||||
|
<foreach collection="array" item="id" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
</mapper>
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
<result property="remark" column="remark"/>
|
<result property="remark" column="remark"/>
|
||||||
<result property="distributionMark" column="distribution_mark"/>
|
<result property="distributionMark" column="distribution_mark"/>
|
||||||
<result property="modelNumber" column="model_number"/>
|
<result property="modelNumber" column="model_number"/>
|
||||||
|
<result property="modelShop" column="model_shop"/>
|
||||||
<result property="link" column="link"/>
|
<result property="link" column="link"/>
|
||||||
<result property="paymentAmount" column="payment_amount"/>
|
<result property="paymentAmount" column="payment_amount"/>
|
||||||
<result property="rebateAmount" column="rebate_amount"/>
|
<result property="rebateAmount" column="rebate_amount"/>
|
||||||
@@ -42,15 +43,16 @@
|
|||||||
<result property="profit" column="profit"/>
|
<result property="profit" column="profit"/>
|
||||||
<result property="sellingPriceManual" column="selling_price_manual"/>
|
<result property="sellingPriceManual" column="selling_price_manual"/>
|
||||||
<result property="profitManual" column="profit_manual"/>
|
<result property="profitManual" column="profit_manual"/>
|
||||||
|
<result property="extraCost" column="extra_cost"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectJDOrderBase">
|
<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,
|
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_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,
|
is_price_protected, price_protected_date, is_invoice_opened, invoice_opened_date, is_review_posted, review_posted_date,
|
||||||
rebate_remark_json, rebate_remark_has_abnormal,
|
rebate_remark_json, rebate_remark_has_abnormal,
|
||||||
selling_price_type, selling_price, profit, selling_price_manual, profit_manual
|
selling_price_type, selling_price, profit, selling_price_manual, profit_manual, extra_cost
|
||||||
from jd_order
|
from jd_order
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
@@ -66,8 +68,18 @@
|
|||||||
)
|
)
|
||||||
</if>
|
</if>
|
||||||
<if test="distributionMark != null and distributionMark != ''"> and distribution_mark = #{distributionMark}</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 != ''">
|
||||||
<if test="modelNumberExclude != null and modelNumberExclude != ''"> and (model_number is null or model_number not like concat('%', #{modelNumberExclude}, '%'))</if>
|
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}, '%'))
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
<if test="link != null and link != ''"> and link like concat('%', #{link}, '%')</if>
|
<if test="link != null and link != ''"> and link like concat('%', #{link}, '%')</if>
|
||||||
<if test="paymentAmount != null"> and payment_amount = #{paymentAmount}</if>
|
<if test="paymentAmount != null"> and payment_amount = #{paymentAmount}</if>
|
||||||
<if test="rebateAmount != null"> and rebate_amount = #{rebateAmount}</if>
|
<if test="rebateAmount != null"> and rebate_amount = #{rebateAmount}</if>
|
||||||
@@ -115,8 +127,18 @@
|
|||||||
)
|
)
|
||||||
</if>
|
</if>
|
||||||
<if test="distributionMark != null and distributionMark != ''"> and distribution_mark = #{distributionMark}</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 != ''">
|
||||||
<if test="modelNumberExclude != null and modelNumberExclude != ''"> and (model_number is null or model_number not like concat('%', #{modelNumberExclude}, '%'))</if>
|
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}, '%'))
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
<if test="link != null and link != ''"> and link like concat('%', #{link}, '%')</if>
|
<if test="link != null and link != ''"> and link like concat('%', #{link}, '%')</if>
|
||||||
<if test="paymentAmount != null"> and payment_amount = #{paymentAmount}</if>
|
<if test="paymentAmount != null"> and payment_amount = #{paymentAmount}</if>
|
||||||
<if test="rebateAmount != null"> and rebate_amount = #{rebateAmount}</if>
|
<if test="rebateAmount != null"> and rebate_amount = #{rebateAmount}</if>
|
||||||
@@ -168,21 +190,21 @@
|
|||||||
|
|
||||||
<insert id="insertJDOrder" parameterType="JDOrder" useGeneratedKeys="true" keyProperty="id">
|
<insert id="insertJDOrder" parameterType="JDOrder" useGeneratedKeys="true" keyProperty="id">
|
||||||
insert into jd_order (
|
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,
|
payment_amount, rebate_amount, address, logistics_link,
|
||||||
tencent_doc_pushed, tencent_doc_push_time,
|
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,
|
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_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,
|
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
|
selling_price_type, selling_price, profit, selling_price_manual, profit_manual, extra_cost
|
||||||
) values (
|
) values (
|
||||||
#{remark}, #{distributionMark}, #{modelNumber}, #{link},
|
#{remark}, #{distributionMark}, #{modelNumber}, #{modelShop}, #{link},
|
||||||
#{paymentAmount}, #{rebateAmount}, #{address}, #{logisticsLink},
|
#{paymentAmount}, #{rebateAmount}, #{address}, #{logisticsLink},
|
||||||
0, null,
|
0, null,
|
||||||
#{orderId}, #{buyer}, #{orderTime}, now(), now(), #{status}, #{isCountEnabled}, #{thirdPartyOrderNo}, #{jingfenActualPrice},
|
#{orderId}, #{buyer}, #{orderTime}, now(), now(), #{status}, #{isCountEnabled}, #{thirdPartyOrderNo}, #{jingfenActualPrice},
|
||||||
#{isRefunded}, #{refundDate}, #{isRefundReceived}, #{refundReceivedDate}, #{isRebateReceived}, #{rebateReceivedDate},
|
#{isRefunded}, #{refundDate}, #{isRefundReceived}, #{refundReceivedDate}, #{isRebateReceived}, #{rebateReceivedDate},
|
||||||
#{isPriceProtected}, #{priceProtectedDate}, #{isInvoiceOpened}, #{invoiceOpenedDate}, #{isReviewPosted}, #{reviewPostedDate},
|
#{isPriceProtected}, #{priceProtectedDate}, #{isInvoiceOpened}, #{invoiceOpenedDate}, #{isReviewPosted}, #{reviewPostedDate},
|
||||||
#{sellingPriceType}, #{sellingPrice}, #{profit}, #{sellingPriceManual}, #{profitManual}
|
#{sellingPriceType}, #{sellingPrice}, #{profit}, #{sellingPriceManual}, #{profitManual}, #{extraCost,jdbcType=DOUBLE}
|
||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
@@ -192,6 +214,7 @@
|
|||||||
<if test="remark != null"> remark = #{remark},</if>
|
<if test="remark != null"> remark = #{remark},</if>
|
||||||
<if test="distributionMark != null"> distribution_mark = #{distributionMark},</if>
|
<if test="distributionMark != null"> distribution_mark = #{distributionMark},</if>
|
||||||
<if test="modelNumber != null"> model_number = #{modelNumber},</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="link != null"> link = #{link},</if>
|
||||||
<if test="paymentAmount != null"> payment_amount = #{paymentAmount},</if>
|
<if test="paymentAmount != null"> payment_amount = #{paymentAmount},</if>
|
||||||
<if test="rebateAmount != null"> rebate_amount = #{rebateAmount},</if>
|
<if test="rebateAmount != null"> rebate_amount = #{rebateAmount},</if>
|
||||||
@@ -220,12 +243,14 @@
|
|||||||
<if test="reviewPostedDate != null"> review_posted_date = #{reviewPostedDate},</if>
|
<if test="reviewPostedDate != null"> review_posted_date = #{reviewPostedDate},</if>
|
||||||
<if test="rebateRemarkJson != null"> rebate_remark_json = #{rebateRemarkJson},</if>
|
<if test="rebateRemarkJson != null"> rebate_remark_json = #{rebateRemarkJson},</if>
|
||||||
<if test="rebateRemarkHasAbnormal != null"> rebate_remark_has_abnormal = #{rebateRemarkHasAbnormal},</if>
|
<if test="rebateRemarkHasAbnormal != null"> rebate_remark_has_abnormal = #{rebateRemarkHasAbnormal},</if>
|
||||||
|
<!-- extra_cost:随列表保存一并写入 applyProfitFields,避免仅写了 profit 却未持久化额外成本 -->
|
||||||
<if test="params != null and params.applyProfitFields != null and params.applyProfitFields == true">
|
<if test="params != null and params.applyProfitFields != null and params.applyProfitFields == true">
|
||||||
selling_price_type = #{sellingPriceType,jdbcType=VARCHAR},
|
selling_price_type = #{sellingPriceType,jdbcType=VARCHAR},
|
||||||
selling_price = #{sellingPrice,jdbcType=DOUBLE},
|
selling_price = #{sellingPrice,jdbcType=DOUBLE},
|
||||||
profit = #{profit,jdbcType=DOUBLE},
|
profit = #{profit,jdbcType=DOUBLE},
|
||||||
selling_price_manual = #{sellingPriceManual,jdbcType=INTEGER},
|
selling_price_manual = #{sellingPriceManual,jdbcType=INTEGER},
|
||||||
profit_manual = #{profitManual,jdbcType=INTEGER},
|
profit_manual = #{profitManual,jdbcType=INTEGER},
|
||||||
|
extra_cost = COALESCE(#{extraCost,jdbcType=DOUBLE}, 0),
|
||||||
</if>
|
</if>
|
||||||
update_time = now()
|
update_time = now()
|
||||||
</set>
|
</set>
|
||||||
@@ -294,24 +319,45 @@
|
|||||||
|
|
||||||
<resultMap id="QuickRecordModelOptionResult" type="com.ruoyi.jarvis.domain.dto.QuickRecordModelOption">
|
<resultMap id="QuickRecordModelOptionResult" type="com.ruoyi.jarvis.domain.dto.QuickRecordModelOption">
|
||||||
<result property="modelNumber" column="model_number"/>
|
<result property="modelNumber" column="model_number"/>
|
||||||
|
<result property="modelShop" column="model_shop"/>
|
||||||
<result property="lastPaymentAmount" column="last_payment_amount"/>
|
<result property="lastPaymentAmount" column="last_payment_amount"/>
|
||||||
<result property="lastRebateAmount" column="last_rebate_amount"/>
|
<result property="lastRebateAmount" column="last_rebate_amount"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<select id="selectQuickRecordModelOptions" resultMap="QuickRecordModelOptionResult">
|
<select id="selectQuickRecordModelOptions" resultMap="QuickRecordModelOptionResult">
|
||||||
select o.model_number as model_number,
|
select o.model_number as model_number,
|
||||||
|
o.model_shop as model_shop,
|
||||||
o.payment_amount as last_payment_amount,
|
o.payment_amount as last_payment_amount,
|
||||||
o.rebate_amount as last_rebate_amount
|
o.rebate_amount as last_rebate_amount
|
||||||
from jd_order o
|
from jd_order o
|
||||||
inner join (
|
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
|
from jd_order
|
||||||
where model_number is not null and trim(model_number) != ''
|
where model_number is not null and trim(model_number) != ''
|
||||||
group by trim(model_number)
|
group by trim(IFNULL(model_number, '')), trim(IFNULL(model_shop, ''))
|
||||||
) t on trim(o.model_number) = t.m and o.id = t.mid
|
) 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
|
order by o.id desc
|
||||||
</select>
|
</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>
|
</mapper>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -398,6 +398,12 @@
|
|||||||
where order_id = #{orderId}
|
where order_id = #{orderId}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectOrderRowsByOrderNo" parameterType="String" resultMap="OrderRowsResult">
|
||||||
|
<include refid="selectOrderRowsVo"/>
|
||||||
|
where order_id = #{orderNo} or parent_id = #{orderNo}
|
||||||
|
order by order_time desc
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectOrderRowsByGiftCouponKey" parameterType="String" resultMap="OrderRowsResult">
|
<select id="selectOrderRowsByGiftCouponKey" parameterType="String" resultMap="OrderRowsResult">
|
||||||
<include refid="selectOrderRowsVo"/>
|
<include refid="selectOrderRowsVo"/>
|
||||||
where gift_coupon_key = #{giftCouponKey}
|
where gift_coupon_key = #{giftCouponKey}
|
||||||
|
|||||||
29
scripts/backfill_goods_info.ps1
Normal file
29
scripts/backfill_goods_info.ps1
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# 京粉订单 goodsInfo 回填脚本(需先部署 Jarvis_java + ruoyi-java,并已登录获取 token)
|
||||||
|
# 用法示例见下方 $body
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$BaseUrl = "https://jarvis.van333.cn/jarvis-api",
|
||||||
|
[string]$Token = "",
|
||||||
|
[string]$OrderIds = "",
|
||||||
|
[switch]$Missing,
|
||||||
|
[int]$Limit = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
$body = @{}
|
||||||
|
if ($Missing) {
|
||||||
|
$body.missing = $true
|
||||||
|
$body.limit = $Limit
|
||||||
|
} elseif ($OrderIds) {
|
||||||
|
$body.orderIds = $OrderIds
|
||||||
|
} else {
|
||||||
|
Write-Host "请指定 -OrderIds '订单号1,订单号2' 或 -Missing"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$headers = @{ "Content-Type" = "application/json" }
|
||||||
|
if ($Token) {
|
||||||
|
$headers.Authorization = "Bearer $Token"
|
||||||
|
}
|
||||||
|
|
||||||
|
$uri = "$BaseUrl/system/jdorder/orderRows/backfillGoodsInfo"
|
||||||
|
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -Body ($body | ConvertTo-Json)
|
||||||
8
sql/backfill_goods_info_preview.sql
Normal file
8
sql/backfill_goods_info_preview.sql
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
-- 预览:待回填 goods_info 的订单号(goods_info_id 为空)
|
||||||
|
SELECT order_id
|
||||||
|
FROM order_rows
|
||||||
|
WHERE goods_info_id IS NULL
|
||||||
|
AND order_id IS NOT NULL
|
||||||
|
GROUP BY order_id
|
||||||
|
ORDER BY MAX(order_time) DESC
|
||||||
|
LIMIT 100;
|
||||||
10
sql/goods_info.sql
Normal file
10
sql/goods_info.sql
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
-- 京东联盟订单商品信息(goodsInfo 字段入库)
|
||||||
|
CREATE TABLE IF NOT EXISTS goods_info (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
|
||||||
|
owner VARCHAR(16) DEFAULT NULL COMMENT 'g=自营 p=pop',
|
||||||
|
main_sku_id VARCHAR(64) DEFAULT NULL COMMENT '自营商品主Id',
|
||||||
|
product_id VARCHAR(64) DEFAULT NULL COMMENT 'POP商品主Id',
|
||||||
|
image_url VARCHAR(512) DEFAULT NULL COMMENT '商品主图',
|
||||||
|
shop_name VARCHAR(255) DEFAULT NULL COMMENT '店铺名称',
|
||||||
|
shop_id VARCHAR(64) DEFAULT NULL COMMENT '店铺Id'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='京东订单商品信息';
|
||||||
2
sql/jd_order_extra_cost.sql
Normal file
2
sql/jd_order_extra_cost.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-- JD 订单:额外成本(计入 F/H-TF 自动利润:利润 = 对客实收 − (付款−后返) − extra_cost)
|
||||||
|
ALTER TABLE jd_order ADD COLUMN extra_cost DOUBLE NOT NULL DEFAULT 0 COMMENT '额外成本,手动录入,默认0' AFTER profit_manual;
|
||||||
2
sql/jd_order_model_shop.sql
Normal file
2
sql/jd_order_model_shop.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-- 京东订单:型号店铺短前缀(与 model_number 拆分存储,便于筛选;完整对外型号 = model_number + model_shop)
|
||||||
|
ALTER TABLE jd_order ADD COLUMN model_shop VARCHAR(64) DEFAULT NULL COMMENT '型号店铺短前缀(如海尔厨房)';
|
||||||
Reference in New Issue
Block a user