增加套餐产品红线价修改内容日志
This commit is contained in:
+54
@@ -0,0 +1,54 @@
|
|||||||
|
package com.bms.web.controller.monitor;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import com.bms.common.constant.HttpStatus;
|
||||||
|
import com.bms.common.core.controller.BaseController;
|
||||||
|
import com.bms.common.core.domain.AjaxResult;
|
||||||
|
import com.bms.common.core.page.PageDomain;
|
||||||
|
import com.bms.common.core.page.TableDataInfo;
|
||||||
|
import com.bms.common.core.page.TableSupport;
|
||||||
|
import com.bms.price.search.BillSearchPage;
|
||||||
|
import com.bms.price.search.EsLogType;
|
||||||
|
import com.bms.price.search.IBillSearchStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Price before-after change log (sales / product / redline) from ES.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/monitor/priceLog")
|
||||||
|
public class PriceLogController extends BaseController
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private IBillSearchStore billSearchStore;
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('monitor:priceLog:list')")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo list(
|
||||||
|
@RequestParam(value = "bizId", required = false) String bizId,
|
||||||
|
@RequestParam(value = "status", required = false) String status)
|
||||||
|
{
|
||||||
|
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||||
|
int pageNum = pageDomain.getPageNum() == null ? 1 : pageDomain.getPageNum().intValue();
|
||||||
|
int pageSize = pageDomain.getPageSize() == null ? 10 : pageDomain.getPageSize().intValue();
|
||||||
|
BillSearchPage page = billSearchStore.search(EsLogType.PRICE_CHANGE, bizId, status, pageNum, pageSize);
|
||||||
|
TableDataInfo rsp = new TableDataInfo();
|
||||||
|
rsp.setCode(HttpStatus.SUCCESS);
|
||||||
|
rsp.setMsg("\u67e5\u8be2\u6210\u529f");
|
||||||
|
rsp.setRows(page.getRows());
|
||||||
|
rsp.setTotal(page.getTotal());
|
||||||
|
return rsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('monitor:priceLog:list')")
|
||||||
|
@GetMapping("/{docId}")
|
||||||
|
public AjaxResult getInfo(@PathVariable("docId") String docId)
|
||||||
|
{
|
||||||
|
return success(billSearchStore.getByDocId(docId));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@ public final class EsLogType
|
|||||||
public static final String ARREARS = "ARREARS";
|
public static final String ARREARS = "ARREARS";
|
||||||
/** Monitor: sync billing from TAB_ORDER */
|
/** Monitor: sync billing from TAB_ORDER */
|
||||||
public static final String ORDER_SOURCE_SYNC = "ORDER_SOURCE_SYNC";
|
public static final String ORDER_SOURCE_SYNC = "ORDER_SOURCE_SYNC";
|
||||||
|
/** Monitor: sales / product / redline price before-after changes */
|
||||||
|
public static final String PRICE_CHANGE = "PRICE_CHANGE";
|
||||||
|
|
||||||
private EsLogType()
|
private EsLogType()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,221 @@
|
|||||||
|
package com.bms.price.search;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.bms.common.utils.SecurityUtils;
|
||||||
|
import com.bms.common.utils.StringUtils;
|
||||||
|
import com.bms.price.domain.PrcPriceSetDetail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write sales / product / redline price before-after changes to ES (bms_biz_log).
|
||||||
|
*/
|
||||||
|
public final class PriceChangeEsLog
|
||||||
|
{
|
||||||
|
public static final String KIND_SALES = "SALES";
|
||||||
|
public static final String KIND_PRODUCT = "PRODUCT";
|
||||||
|
public static final String KIND_REDLINE = "REDLINE";
|
||||||
|
|
||||||
|
public static final String ACTION_INSERT = "INSERT";
|
||||||
|
public static final String ACTION_UPDATE = "UPDATE";
|
||||||
|
public static final String ACTION_DELETE = "DELETE";
|
||||||
|
public static final String ACTION_IMPORT = "IMPORT";
|
||||||
|
|
||||||
|
private PriceChangeEsLog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String operator()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String name = SecurityUtils.getUsername();
|
||||||
|
return StringUtils.isEmpty(name) ? "unknown" : name;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> change(String field, String fieldLabel, Object oldValue, Object newValue)
|
||||||
|
{
|
||||||
|
Map<String, String> row = new LinkedHashMap<String, String>();
|
||||||
|
row.put("field", field);
|
||||||
|
row.put("fieldLabel", fieldLabel);
|
||||||
|
row.put("oldValue", stringify(oldValue));
|
||||||
|
row.put("newValue", stringify(newValue));
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean valuesEqual(Object a, Object b)
|
||||||
|
{
|
||||||
|
if (a == null && b == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a instanceof BigDecimal || b instanceof BigDecimal)
|
||||||
|
{
|
||||||
|
BigDecimal ba = toDecimal(a);
|
||||||
|
BigDecimal bb = toDecimal(b);
|
||||||
|
if (ba == null && bb == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ba == null || bb == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ba.compareTo(bb) == 0;
|
||||||
|
}
|
||||||
|
return Objects.equals(stringify(a), stringify(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addIfChanged(List<Map<String, String>> changes, String field, String fieldLabel,
|
||||||
|
Object oldValue, Object newValue)
|
||||||
|
{
|
||||||
|
if (changes == null || valuesEqual(oldValue, newValue))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
changes.add(change(field, fieldLabel, oldValue, newValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sales detail price fields (freight / registration / discount). */
|
||||||
|
public static List<Map<String, String>> diffSalesDetail(PrcPriceSetDetail oldRow, PrcPriceSetDetail newRow)
|
||||||
|
{
|
||||||
|
List<Map<String, String>> changes = new ArrayList<Map<String, String>>();
|
||||||
|
if (newRow == null)
|
||||||
|
{
|
||||||
|
if (oldRow != null)
|
||||||
|
{
|
||||||
|
addIfChanged(changes, "fvValue", "\u8fd0\u8d39\u5355\u4ef7", oldRow.getFvValue(), null);
|
||||||
|
addIfChanged(changes, "fvRegistrationFee", "\u6302\u53f7\u8d39", oldRow.getFvRegistrationFee(), null);
|
||||||
|
addIfChanged(changes, "discountValue", "\u6298\u6263", oldRow.getDiscountValue(), null);
|
||||||
|
}
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
Object oldFv = oldRow == null ? null : oldRow.getFvValue();
|
||||||
|
Object oldReg = oldRow == null ? null : oldRow.getFvRegistrationFee();
|
||||||
|
Object oldDisc = oldRow == null ? null : oldRow.getDiscountValue();
|
||||||
|
addIfChanged(changes, "fvValue", "\u8fd0\u8d39\u5355\u4ef7", oldFv, newRow.getFvValue());
|
||||||
|
addIfChanged(changes, "fvRegistrationFee", "\u6302\u53f7\u8d39", oldReg, newRow.getFvRegistrationFee());
|
||||||
|
addIfChanged(changes, "discountValue", "\u6298\u6263", oldDisc, newRow.getDiscountValue());
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Map<String, String>> diffCatalogPrice(BigDecimal oldFreight, BigDecimal oldReg,
|
||||||
|
BigDecimal newFreight, BigDecimal newReg)
|
||||||
|
{
|
||||||
|
List<Map<String, String>> changes = new ArrayList<Map<String, String>>();
|
||||||
|
addIfChanged(changes, "freightPrice", "\u8fd0\u8d39\u5355\u4ef7", oldFreight, newFreight);
|
||||||
|
addIfChanged(changes, "registrationFee", "\u6302\u53f7\u8d39", oldReg, newReg);
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Object> bizKeysSales(PrcPriceSetDetail d)
|
||||||
|
{
|
||||||
|
Map<String, Object> keys = new LinkedHashMap<String, Object>();
|
||||||
|
if (d == null)
|
||||||
|
{
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
keys.put("psdId", d.getPsdId());
|
||||||
|
keys.put("psvId", d.getPsvId());
|
||||||
|
keys.put("productCode", d.getProductCode());
|
||||||
|
keys.put("productName", d.getProductName());
|
||||||
|
keys.put("countryCode", d.getCountryCode());
|
||||||
|
keys.put("countryName", d.getCountryName());
|
||||||
|
keys.put("zoneCode", d.getZoneCode());
|
||||||
|
keys.put("weightMin", d.getWeightMin());
|
||||||
|
keys.put("weightMax", d.getWeightMax());
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void save(IBillSearchStore store, String bizId, String priceKind, String action,
|
||||||
|
Map<String, Object> bizKeys, List<Map<String, String>> changes)
|
||||||
|
{
|
||||||
|
save(store, bizId, priceKind, action, bizKeys, changes, null, EsBizLogSupport.STATUS_SUCCESS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void save(IBillSearchStore store, String bizId, String priceKind, String action,
|
||||||
|
Map<String, Object> bizKeys, List<Map<String, String>> changes, Object extra,
|
||||||
|
String status, String errorMessage)
|
||||||
|
{
|
||||||
|
if (store == null || StringUtils.isEmpty(bizId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (changes != null && changes.isEmpty() && extra == null
|
||||||
|
&& !ACTION_DELETE.equals(action) && !ACTION_INSERT.equals(action))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<String, Object> req = new LinkedHashMap<String, Object>();
|
||||||
|
req.put("action", action);
|
||||||
|
req.put("operator", operator());
|
||||||
|
req.put("priceKind", priceKind);
|
||||||
|
req.put("bizKeys", bizKeys);
|
||||||
|
req.put("changes", changes == null ? new ArrayList<Map<String, String>>() : changes);
|
||||||
|
if (extra != null)
|
||||||
|
{
|
||||||
|
req.put("extra", extra);
|
||||||
|
}
|
||||||
|
Map<String, Object> resp = new LinkedHashMap<String, Object>();
|
||||||
|
resp.put("success", !EsBizLogSupport.STATUS_FAIL.equals(status));
|
||||||
|
String st = StringUtils.isEmpty(status) ? EsBizLogSupport.STATUS_SUCCESS : status;
|
||||||
|
store.save(EsLogType.PRICE_CHANGE, bizId, JSON.toJSONString(req), JSON.toJSONString(resp), st, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String bizIdSales(Long psdId)
|
||||||
|
{
|
||||||
|
return "SALES_" + (psdId == null ? System.currentTimeMillis() : psdId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String bizIdProduct(Long detailId)
|
||||||
|
{
|
||||||
|
return "PRODUCT_" + (detailId == null ? System.currentTimeMillis() : detailId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String bizIdRedline(Long detailId)
|
||||||
|
{
|
||||||
|
return "REDLINE_" + (detailId == null ? System.currentTimeMillis() : detailId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String stringify(Object v)
|
||||||
|
{
|
||||||
|
if (v == null)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (v instanceof BigDecimal)
|
||||||
|
{
|
||||||
|
return ((BigDecimal) v).stripTrailingZeros().toPlainString();
|
||||||
|
}
|
||||||
|
return String.valueOf(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BigDecimal toDecimal(Object v)
|
||||||
|
{
|
||||||
|
if (v == null || "".equals(v))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (v instanceof BigDecimal)
|
||||||
|
{
|
||||||
|
return (BigDecimal) v;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new BigDecimal(String.valueOf(v).trim());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+35
-2
@@ -39,10 +39,14 @@ import com.bms.price.domain.BmsProductCountry;
|
|||||||
import com.bms.price.domain.BmsProductImportTask;
|
import com.bms.price.domain.BmsProductImportTask;
|
||||||
import com.bms.price.domain.CatalogPreviewApplyRequest;
|
import com.bms.price.domain.CatalogPreviewApplyRequest;
|
||||||
import com.bms.price.domain.PrcZone;
|
import com.bms.price.domain.PrcZone;
|
||||||
|
import com.bms.price.domain.PrcPriceSetDetail;
|
||||||
import com.bms.price.mapper.BmsProductCountryMapper;
|
import com.bms.price.mapper.BmsProductCountryMapper;
|
||||||
import com.bms.price.mapper.BmsProductMapper;
|
import com.bms.price.mapper.BmsProductMapper;
|
||||||
|
import com.bms.price.mapper.PrcPriceSetDetailMapper;
|
||||||
import com.bms.price.mapper.PrcZoneMapper;
|
import com.bms.price.mapper.PrcZoneMapper;
|
||||||
import com.bms.price.domain.PrcPriceExcelFile;
|
import com.bms.price.domain.PrcPriceExcelFile;
|
||||||
|
import com.bms.price.search.IBillSearchStore;
|
||||||
|
import com.bms.price.search.PriceChangeEsLog;
|
||||||
import com.bms.price.service.IBmsProductService;
|
import com.bms.price.service.IBmsProductService;
|
||||||
import com.bms.price.service.IPrcPriceExcelFileService;
|
import com.bms.price.service.IPrcPriceExcelFileService;
|
||||||
import com.bms.price.service.IPrcSurchargeRelService;
|
import com.bms.price.service.IPrcSurchargeRelService;
|
||||||
@@ -106,6 +110,12 @@ public class BmsProductServiceImpl implements IBmsProductService
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IPrcPriceExcelFileService priceExcelFileService;
|
private IPrcPriceExcelFileService priceExcelFileService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PrcPriceSetDetailMapper detailMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBillSearchStore billSearchStore;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BmsProduct selectBmsProductById(Long productId)
|
public BmsProduct selectBmsProductById(Long productId)
|
||||||
{
|
{
|
||||||
@@ -164,13 +174,36 @@ public class BmsProductServiceImpl implements IBmsProductService
|
|||||||
{
|
{
|
||||||
if (country == null || country.getDetailId() == null)
|
if (country == null || country.getDetailId() == null)
|
||||||
{
|
{
|
||||||
throw new ServiceException("明细行主键缺失,无法修改");
|
throw new ServiceException("\u660e\u7ec6\u884c\u4e3b\u952e\u7f3a\u5931\uff0c\u65e0\u6cd5\u4fee\u6539");
|
||||||
}
|
}
|
||||||
|
PrcPriceSetDetail old = detailMapper.selectPrcPriceSetDetailById(country.getDetailId());
|
||||||
int rows = countryMapper.updateBmsProductCountry(country);
|
int rows = countryMapper.updateBmsProductCountry(country);
|
||||||
if (rows > 0)
|
if (rows > 0)
|
||||||
{
|
{
|
||||||
// 生效/失效日期可能变化,状态按日期重算
|
// Recalc status when effective/expire dates change
|
||||||
countryMapper.refreshStatusByDates();
|
countryMapper.refreshStatusByDates();
|
||||||
|
List<Map<String, String>> changes = PriceChangeEsLog.diffCatalogPrice(
|
||||||
|
old == null ? null : old.getFvValue(),
|
||||||
|
old == null ? null : old.getFvRegistrationFee(),
|
||||||
|
country.getFreightPrice(),
|
||||||
|
country.getRegistrationFee());
|
||||||
|
if (!changes.isEmpty())
|
||||||
|
{
|
||||||
|
Map<String, Object> keys = new LinkedHashMap<String, Object>();
|
||||||
|
keys.put("detailId", country.getDetailId());
|
||||||
|
keys.put("productCode", country.getProductCode() != null ? country.getProductCode()
|
||||||
|
: (old == null ? null : old.getProductCode()));
|
||||||
|
keys.put("countryCode", country.getCountryCode() != null ? country.getCountryCode()
|
||||||
|
: (old == null ? null : old.getCountryCode()));
|
||||||
|
keys.put("zoneCode", country.getZoneCode() != null ? country.getZoneCode()
|
||||||
|
: (old == null ? null : old.getZoneCode()));
|
||||||
|
keys.put("weightMin", country.getWeightMin() != null ? country.getWeightMin()
|
||||||
|
: (old == null ? null : old.getWeightMin()));
|
||||||
|
keys.put("weightMax", country.getWeightMax() != null ? country.getWeightMax()
|
||||||
|
: (old == null ? null : old.getWeightMax()));
|
||||||
|
PriceChangeEsLog.save(billSearchStore, PriceChangeEsLog.bizIdProduct(country.getDetailId()),
|
||||||
|
PriceChangeEsLog.KIND_PRODUCT, PriceChangeEsLog.ACTION_UPDATE, keys, changes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-2
@@ -40,11 +40,15 @@ import com.bms.price.domain.BmsRedlineProductImportTask;
|
|||||||
import com.bms.price.domain.RedlineCatalogPreviewApplyRequest;
|
import com.bms.price.domain.RedlineCatalogPreviewApplyRequest;
|
||||||
import com.bms.price.domain.PrcZone;
|
import com.bms.price.domain.PrcZone;
|
||||||
import com.bms.price.domain.PrcSurchargeRel;
|
import com.bms.price.domain.PrcSurchargeRel;
|
||||||
|
import com.bms.price.domain.PrcPriceSetDetail;
|
||||||
import com.bms.price.mapper.BmsRedlineProductCountryMapper;
|
import com.bms.price.mapper.BmsRedlineProductCountryMapper;
|
||||||
import com.bms.price.mapper.BmsRedlineProductMapper;
|
import com.bms.price.mapper.BmsRedlineProductMapper;
|
||||||
|
import com.bms.price.mapper.PrcPriceSetDetailMapper;
|
||||||
import com.bms.price.mapper.PrcSurchargeRelMapper;
|
import com.bms.price.mapper.PrcSurchargeRelMapper;
|
||||||
import com.bms.price.mapper.PrcZoneMapper;
|
import com.bms.price.mapper.PrcZoneMapper;
|
||||||
import com.bms.price.domain.PrcPriceExcelFile;
|
import com.bms.price.domain.PrcPriceExcelFile;
|
||||||
|
import com.bms.price.search.IBillSearchStore;
|
||||||
|
import com.bms.price.search.PriceChangeEsLog;
|
||||||
import com.bms.price.service.IBmsRedlineProductService;
|
import com.bms.price.service.IBmsRedlineProductService;
|
||||||
import com.bms.price.service.IPrcPriceExcelFileService;
|
import com.bms.price.service.IPrcPriceExcelFileService;
|
||||||
import com.bms.price.domain.PriceType;
|
import com.bms.price.domain.PriceType;
|
||||||
@@ -107,6 +111,12 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IPrcPriceExcelFileService priceExcelFileService;
|
private IPrcPriceExcelFileService priceExcelFileService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PrcPriceSetDetailMapper detailMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBillSearchStore billSearchStore;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BmsRedlineProduct selectBmsRedlineProductById(Long productId)
|
public BmsRedlineProduct selectBmsRedlineProductById(Long productId)
|
||||||
{
|
{
|
||||||
@@ -165,13 +175,36 @@ public class BmsRedlineProductServiceImpl implements IBmsRedlineProductService
|
|||||||
{
|
{
|
||||||
if (country == null || country.getDetailId() == null)
|
if (country == null || country.getDetailId() == null)
|
||||||
{
|
{
|
||||||
throw new ServiceException("明细行主键缺失,无法修改");
|
throw new ServiceException("\u660e\u7ec6\u884c\u4e3b\u952e\u7f3a\u5931\uff0c\u65e0\u6cd5\u4fee\u6539");
|
||||||
}
|
}
|
||||||
|
PrcPriceSetDetail old = detailMapper.selectPrcPriceSetDetailById(country.getDetailId());
|
||||||
int rows = countryMapper.updateBmsRedlineProductCountry(country);
|
int rows = countryMapper.updateBmsRedlineProductCountry(country);
|
||||||
if (rows > 0)
|
if (rows > 0)
|
||||||
{
|
{
|
||||||
// 生效/失效日期可能变化,状态按日期重算
|
// Recalc status when effective/expire dates change
|
||||||
countryMapper.refreshStatusByDates();
|
countryMapper.refreshStatusByDates();
|
||||||
|
List<Map<String, String>> changes = PriceChangeEsLog.diffCatalogPrice(
|
||||||
|
old == null ? null : old.getFvValue(),
|
||||||
|
old == null ? null : old.getFvRegistrationFee(),
|
||||||
|
country.getFreightPrice(),
|
||||||
|
country.getRegistrationFee());
|
||||||
|
if (!changes.isEmpty())
|
||||||
|
{
|
||||||
|
Map<String, Object> keys = new LinkedHashMap<String, Object>();
|
||||||
|
keys.put("detailId", country.getDetailId());
|
||||||
|
keys.put("productCode", country.getProductCode() != null ? country.getProductCode()
|
||||||
|
: (old == null ? null : old.getProductCode()));
|
||||||
|
keys.put("countryCode", country.getCountryCode() != null ? country.getCountryCode()
|
||||||
|
: (old == null ? null : old.getCountryCode()));
|
||||||
|
keys.put("zoneCode", country.getZoneCode() != null ? country.getZoneCode()
|
||||||
|
: (old == null ? null : old.getZoneCode()));
|
||||||
|
keys.put("weightMin", country.getWeightMin() != null ? country.getWeightMin()
|
||||||
|
: (old == null ? null : old.getWeightMin()));
|
||||||
|
keys.put("weightMax", country.getWeightMax() != null ? country.getWeightMax()
|
||||||
|
: (old == null ? null : old.getWeightMax()));
|
||||||
|
PriceChangeEsLog.save(billSearchStore, PriceChangeEsLog.bizIdRedline(country.getDetailId()),
|
||||||
|
PriceChangeEsLog.KIND_REDLINE, PriceChangeEsLog.ACTION_UPDATE, keys, changes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|||||||
+65
@@ -51,6 +51,8 @@ import com.bms.price.mapper.PrcSurchargeRelMapper;
|
|||||||
import com.bms.common.core.domain.entity.SysUser;
|
import com.bms.common.core.domain.entity.SysUser;
|
||||||
import com.bms.system.mapper.SysUserMapper;
|
import com.bms.system.mapper.SysUserMapper;
|
||||||
import com.bms.price.service.IBmsProductService;
|
import com.bms.price.service.IBmsProductService;
|
||||||
|
import com.bms.price.search.IBillSearchStore;
|
||||||
|
import com.bms.price.search.PriceChangeEsLog;
|
||||||
import com.bms.price.service.IPrcPriceExcelFileService;
|
import com.bms.price.service.IPrcPriceExcelFileService;
|
||||||
import com.bms.price.service.IPrcPriceSetService;
|
import com.bms.price.service.IPrcPriceSetService;
|
||||||
import com.bms.price.task.PrcPriceSetSaveAsyncRunner;
|
import com.bms.price.task.PrcPriceSetSaveAsyncRunner;
|
||||||
@@ -129,6 +131,9 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IPrcPriceExcelFileService priceExcelFileService;
|
private IPrcPriceExcelFileService priceExcelFileService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IBillSearchStore billSearchStore;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrcPriceSet selectPrcPriceSetById(Long priceSetId)
|
public PrcPriceSet selectPrcPriceSetById(Long priceSetId)
|
||||||
{
|
{
|
||||||
@@ -1505,8 +1510,27 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
}
|
}
|
||||||
if (!deleteIds.isEmpty())
|
if (!deleteIds.isEmpty())
|
||||||
{
|
{
|
||||||
|
Map<Long, PrcPriceSetDetail> beforeReplace = new HashMap<Long, PrcPriceSetDetail>();
|
||||||
|
for (PrcPriceSetDetail d : details)
|
||||||
|
{
|
||||||
|
if (d != null && d.getPsdId() != null && deleteIds.contains(d.getPsdId()))
|
||||||
|
{
|
||||||
|
beforeReplace.put(d.getPsdId(), d);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Draft/pending: hard delete covered rows; effect/expired: soft delete.
|
// Draft/pending: hard delete covered rows; effect/expired: soft delete.
|
||||||
deleteDetailRowsByIds(deleteIds, isDraftOrPendingVersionStatus(resolveVersionStatus(psvId)));
|
deleteDetailRowsByIds(deleteIds, isDraftOrPendingVersionStatus(resolveVersionStatus(psvId)));
|
||||||
|
for (Long id : deleteIds)
|
||||||
|
{
|
||||||
|
PrcPriceSetDetail old = beforeReplace.get(id);
|
||||||
|
if (old == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PriceChangeEsLog.save(billSearchStore, PriceChangeEsLog.bizIdSales(id),
|
||||||
|
PriceChangeEsLog.KIND_SALES, PriceChangeEsLog.ACTION_IMPORT,
|
||||||
|
PriceChangeEsLog.bizKeysSales(old), PriceChangeEsLog.diffSalesDetail(old, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
removeDetailsByReplaceScopes(details, detailIndex, replaceScopes);
|
removeDetailsByReplaceScopes(details, detailIndex, replaceScopes);
|
||||||
}
|
}
|
||||||
@@ -1573,6 +1597,8 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
BigDecimal oldFv = hit.getFvValue();
|
||||||
|
BigDecimal oldReg = hit.getFvRegistrationFee();
|
||||||
detailMapper.updateDetailPrices(hit.getPsdId(), freight, registration);
|
detailMapper.updateDetailPrices(hit.getPsdId(), freight, registration);
|
||||||
if (freight != null)
|
if (freight != null)
|
||||||
{
|
{
|
||||||
@@ -1582,6 +1608,14 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
{
|
{
|
||||||
hit.setFvRegistrationFee(registration);
|
hit.setFvRegistrationFee(registration);
|
||||||
}
|
}
|
||||||
|
List<Map<String, String>> changes = PriceChangeEsLog.diffSalesDetail(
|
||||||
|
buildPriceSnapshot(oldFv, oldReg), hit);
|
||||||
|
if (!changes.isEmpty())
|
||||||
|
{
|
||||||
|
PriceChangeEsLog.save(billSearchStore, PriceChangeEsLog.bizIdSales(hit.getPsdId()),
|
||||||
|
PriceChangeEsLog.KIND_SALES, PriceChangeEsLog.ACTION_IMPORT,
|
||||||
|
PriceChangeEsLog.bizKeysSales(hit), changes);
|
||||||
|
}
|
||||||
touched.add(hit.getPsdId());
|
touched.add(hit.getPsdId());
|
||||||
updated++;
|
updated++;
|
||||||
}
|
}
|
||||||
@@ -1606,6 +1640,9 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
{
|
{
|
||||||
touched.add(created.getPsdId());
|
touched.add(created.getPsdId());
|
||||||
}
|
}
|
||||||
|
PriceChangeEsLog.save(billSearchStore, PriceChangeEsLog.bizIdSales(created.getPsdId()),
|
||||||
|
PriceChangeEsLog.KIND_SALES, PriceChangeEsLog.ACTION_IMPORT,
|
||||||
|
PriceChangeEsLog.bizKeysSales(created), PriceChangeEsLog.diffSalesDetail(null, created));
|
||||||
inserted++;
|
inserted++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2116,6 +2153,16 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
{
|
{
|
||||||
replaceSalesSurchargeRels(java.util.Collections.singletonList(detail));
|
replaceSalesSurchargeRels(java.util.Collections.singletonList(detail));
|
||||||
}
|
}
|
||||||
|
if (rows > 0)
|
||||||
|
{
|
||||||
|
List<Map<String, String>> changes = PriceChangeEsLog.diffSalesDetail(old, detail);
|
||||||
|
if (!changes.isEmpty())
|
||||||
|
{
|
||||||
|
PriceChangeEsLog.save(billSearchStore, PriceChangeEsLog.bizIdSales(old.getPsdId()),
|
||||||
|
PriceChangeEsLog.KIND_SALES, PriceChangeEsLog.ACTION_UPDATE,
|
||||||
|
PriceChangeEsLog.bizKeysSales(detail.getPsdId() != null ? detail : old), changes);
|
||||||
|
}
|
||||||
|
}
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2130,6 +2177,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
List<Long> softIds = new ArrayList<Long>();
|
List<Long> softIds = new ArrayList<Long>();
|
||||||
Set<String> hardTouchKeys = new HashSet<String>();
|
Set<String> hardTouchKeys = new HashSet<String>();
|
||||||
Set<String> softTouchKeys = new HashSet<String>();
|
Set<String> softTouchKeys = new HashSet<String>();
|
||||||
|
List<PrcPriceSetDetail> deletedSnapshots = new ArrayList<PrcPriceSetDetail>();
|
||||||
for (Long id : psdIds)
|
for (Long id : psdIds)
|
||||||
{
|
{
|
||||||
if (id == null)
|
if (id == null)
|
||||||
@@ -2143,6 +2191,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
}
|
}
|
||||||
PrcPriceSet db = requireSet(resolvePriceSetIdByPsvId(old.getPsvId()));
|
PrcPriceSet db = requireSet(resolvePriceSetIdByPsvId(old.getPsvId()));
|
||||||
assertChildEditable(db);
|
assertChildEditable(db);
|
||||||
|
deletedSnapshots.add(old);
|
||||||
boolean hard = isDraftOrPendingVersionStatus(resolveVersionStatus(old.getPsvId()));
|
boolean hard = isDraftOrPendingVersionStatus(resolveVersionStatus(old.getPsvId()));
|
||||||
if (hard)
|
if (hard)
|
||||||
{
|
{
|
||||||
@@ -2172,6 +2221,13 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
rows += deleteDetailRowsByIds(softIds, false);
|
rows += deleteDetailRowsByIds(softIds, false);
|
||||||
cleanupOrphanSetProducts(softTouchKeys, false);
|
cleanupOrphanSetProducts(softTouchKeys, false);
|
||||||
}
|
}
|
||||||
|
for (PrcPriceSetDetail old : deletedSnapshots)
|
||||||
|
{
|
||||||
|
List<Map<String, String>> changes = PriceChangeEsLog.diffSalesDetail(old, null);
|
||||||
|
PriceChangeEsLog.save(billSearchStore, PriceChangeEsLog.bizIdSales(old.getPsdId()),
|
||||||
|
PriceChangeEsLog.KIND_SALES, PriceChangeEsLog.ACTION_DELETE,
|
||||||
|
PriceChangeEsLog.bizKeysSales(old), changes);
|
||||||
|
}
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2195,6 +2251,15 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
return detailMapper.deletePrcPriceSetDetailByIds(arr);
|
return detailMapper.deletePrcPriceSetDetailByIds(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Snapshot freight/registration for import before-after log. */
|
||||||
|
private PrcPriceSetDetail buildPriceSnapshot(BigDecimal fvValue, BigDecimal registrationFee)
|
||||||
|
{
|
||||||
|
PrcPriceSetDetail snap = new PrcPriceSetDetail();
|
||||||
|
snap.setFvValue(fvValue);
|
||||||
|
snap.setFvRegistrationFee(registrationFee);
|
||||||
|
return snap;
|
||||||
|
}
|
||||||
|
|
||||||
/** Version status draft(0) / pending(3): hard delete children. */
|
/** Version status draft(0) / pending(3): hard delete children. */
|
||||||
private boolean isDraftOrPendingVersionStatus(String status)
|
private boolean isDraftOrPendingVersionStatus(String status)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
-- Price change log under system monitor
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
|
SET @monitorParent := (
|
||||||
|
SELECT menu_id FROM sys_menu
|
||||||
|
WHERE menu_type = 'M' AND (path = 'monitor' OR menu_name = N'系统监控')
|
||||||
|
ORDER BY menu_id
|
||||||
|
LIMIT 1
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_id, menu_name, parent_id, order_num, path, component, query, route_name,
|
||||||
|
is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark
|
||||||
|
)
|
||||||
|
SELECT 2350, N'价格日志', IFNULL(@monitorParent, 2), 10,
|
||||||
|
'priceLog', 'monitor/priceLog/index', '', 'PriceLog',
|
||||||
|
1, 0, 'C', '0', '0', 'monitor:priceLog:list', 'log', 'admin', sysdate(),
|
||||||
|
N'销售价/产品价/红线价改前改后(ES)'
|
||||||
|
FROM DUAL
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2350 OR perms = 'monitor:priceLog:list');
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (
|
||||||
|
menu_id, menu_name, parent_id, order_num, path, component,
|
||||||
|
is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time
|
||||||
|
)
|
||||||
|
SELECT 2351, N'查询', 2350, 1, '', NULL,
|
||||||
|
1, 0, 'F', '0', '0', 'monitor:priceLog:list', '#', 'admin', sysdate()
|
||||||
|
FROM DUAL
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2351);
|
||||||
|
|
||||||
|
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||||
|
SELECT 1, m.menu_id
|
||||||
|
FROM (SELECT 2350 AS menu_id UNION SELECT 2351) m
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM sys_role_menu rm WHERE rm.role_id = 1 AND rm.menu_id = m.menu_id
|
||||||
|
);
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function listPriceLog(query) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/priceLog/list',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPriceLog(docId) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor/priceLog/' + encodeURIComponent(docId),
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -81,7 +81,8 @@ const typeOptions = [
|
|||||||
{ label: '试算', value: 'QUOTE' },
|
{ label: '试算', value: 'QUOTE' },
|
||||||
{ label: '扣减额度', value: 'CREDIT' },
|
{ label: '扣减额度', value: 'CREDIT' },
|
||||||
{ label: '欠费清除', value: 'ARREARS' },
|
{ label: '欠费清除', value: 'ARREARS' },
|
||||||
{ label: '订单数据源同步', value: 'ORDER_SOURCE_SYNC' }
|
{ label: '订单数据源同步', value: 'ORDER_SOURCE_SYNC' },
|
||||||
|
{ label: '价格变更', value: 'PRICE_CHANGE' }
|
||||||
]
|
]
|
||||||
|
|
||||||
const statusOptions = [
|
const statusOptions = [
|
||||||
|
|||||||
@@ -0,0 +1,265 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<basic-table
|
||||||
|
ref="tableRef"
|
||||||
|
:columns="columns"
|
||||||
|
:search-columns="searchColumns"
|
||||||
|
:query="queryList"
|
||||||
|
row-key="docId"
|
||||||
|
>
|
||||||
|
<template #col-priceKind="{ row }">
|
||||||
|
<el-tag size="small" :type="kindTag(row)">{{ kindLabel(row) }}</el-tag>
|
||||||
|
</template>
|
||||||
|
<template #col-actionName="{ row }">
|
||||||
|
{{ actionLabel(row) }}
|
||||||
|
</template>
|
||||||
|
<template #col-operator="{ row }">
|
||||||
|
{{ operatorOf(row) }}
|
||||||
|
</template>
|
||||||
|
<template #col-productCode="{ row }">
|
||||||
|
{{ productCodeOf(row) }}
|
||||||
|
</template>
|
||||||
|
<template #col-status="{ row }">
|
||||||
|
<el-tag size="small" :type="statusTag(row.status)">{{ statusLabel(row.status) }}</el-tag>
|
||||||
|
</template>
|
||||||
|
<template #col-action="{ row }">
|
||||||
|
<el-button link type="primary" icon="View" @click="handleView(row)" v-hasPermi="['monitor:priceLog:list']">查看</el-button>
|
||||||
|
</template>
|
||||||
|
</basic-table>
|
||||||
|
|
||||||
|
<el-drawer v-model="open" size="760px" :title="drawerTitle" append-to-body destroy-on-close>
|
||||||
|
<div v-loading="loading">
|
||||||
|
<el-empty v-if="!detail" description="暂无详情" />
|
||||||
|
<div v-else>
|
||||||
|
<el-descriptions :column="2" border size="small" class="mb12">
|
||||||
|
<el-descriptions-item label="价格类型">
|
||||||
|
<el-tag size="small" :type="kindTag(detail)">{{ kindLabel(detail) }}</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="操作">{{ actionLabel(detail) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="操作人">{{ operatorOf(detail) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态">
|
||||||
|
<el-tag size="small" :type="statusTag(detail.status)">{{ statusLabel(detail.status) }}</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="业务ID">{{ detail.bizId || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="写入时间">{{ detail.updateTime || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="产品代码">{{ productCodeOf(detail) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="国家">{{ countryOf(detail) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="detail.errorMessage" label="错误信息" :span="2">
|
||||||
|
<span class="err-text">{{ detail.errorMessage }}</span>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
|
<div class="change-panel">
|
||||||
|
<div class="change-panel__head">改前改后</div>
|
||||||
|
<el-table :data="changesOf(detail)" border size="small" empty-text="无字段变更">
|
||||||
|
<el-table-column prop="fieldLabel" label="字段" min-width="120" />
|
||||||
|
<el-table-column prop="oldValue" label="改前" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="newValue" label="改后" min-width="140" show-overflow-tooltip />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="json-panel">
|
||||||
|
<div class="json-panel__head">
|
||||||
|
<span>请求报文</span>
|
||||||
|
<el-button size="small" icon="CopyDocument" @click="copyJson(detail.requestJson)">复制</el-button>
|
||||||
|
</div>
|
||||||
|
<pre class="code-pre">{{ formatJson(detail.requestJson) }}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="PriceLog">
|
||||||
|
import { listPriceLog, getPriceLog } from '@/api/monitor/priceLog'
|
||||||
|
|
||||||
|
const tableRef = ref()
|
||||||
|
const open = ref(false)
|
||||||
|
const loading = ref(false)
|
||||||
|
const detail = ref(null)
|
||||||
|
const drawerTitle = ref('价格日志详情')
|
||||||
|
|
||||||
|
const kindOptions = [
|
||||||
|
{ label: '销售价', value: 'SALES' },
|
||||||
|
{ label: '产品价', value: 'PRODUCT' },
|
||||||
|
{ label: '红线价', value: 'REDLINE' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const actionOptions = [
|
||||||
|
{ label: '新增', value: 'INSERT' },
|
||||||
|
{ label: '修改', value: 'UPDATE' },
|
||||||
|
{ label: '删除', value: 'DELETE' },
|
||||||
|
{ label: '导入', value: 'IMPORT' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const statusOptions = [
|
||||||
|
{ label: '成功', value: 'SUCCESS' },
|
||||||
|
{ label: '失败', value: 'FAIL' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const searchColumns = [
|
||||||
|
{ label: '状态', prop: 'status', component: 'select', options: statusOptions, placeholder: '请选择状态', width: '140px', props: { clearable: true } },
|
||||||
|
{ label: '业务ID', prop: 'bizId', component: 'input', placeholder: 'SALES_/PRODUCT_/REDLINE_', width: '240px' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ label: '价格类型', prop: 'priceKind', align: 'center', width: 100, slot: 'priceKind' },
|
||||||
|
{ label: '操作', prop: 'actionName', align: 'center', width: 90, slot: 'actionName' },
|
||||||
|
{ label: '操作人', prop: 'operator', width: 110, slot: 'operator', showOverflowTooltip: true },
|
||||||
|
{ label: '产品代码', prop: 'productCode', minWidth: 120, slot: 'productCode', showOverflowTooltip: true },
|
||||||
|
{ label: '状态', prop: 'status', align: 'center', width: 90, slot: 'status' },
|
||||||
|
{ label: '业务ID', prop: 'bizId', minWidth: 160, showOverflowTooltip: true },
|
||||||
|
{ label: '写入时间', prop: 'updateTime', align: 'center', width: 180 },
|
||||||
|
{ label: '操作', prop: 'action', align: 'center', width: 90, fixed: 'right', slot: 'action', showInToolbar: false }
|
||||||
|
]
|
||||||
|
|
||||||
|
function queryList(params) {
|
||||||
|
return listPriceLog(params)
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseReq(row) {
|
||||||
|
if (!row || !row.requestJson) return {}
|
||||||
|
try {
|
||||||
|
return typeof row.requestJson === 'object' ? row.requestJson : JSON.parse(row.requestJson)
|
||||||
|
} catch (e) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function kindOf(row) {
|
||||||
|
const req = parseReq(row)
|
||||||
|
return req.priceKind || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function kindLabel(row) {
|
||||||
|
const v = kindOf(row)
|
||||||
|
const found = kindOptions.find(i => i.value === v)
|
||||||
|
return found ? found.label : (v || '-')
|
||||||
|
}
|
||||||
|
|
||||||
|
function kindTag(row) {
|
||||||
|
const v = kindOf(row)
|
||||||
|
if (v === 'SALES') return 'success'
|
||||||
|
if (v === 'PRODUCT') return 'warning'
|
||||||
|
if (v === 'REDLINE') return 'danger'
|
||||||
|
return 'info'
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionLabel(row) {
|
||||||
|
const req = parseReq(row)
|
||||||
|
const found = actionOptions.find(i => i.value === req.action)
|
||||||
|
return found ? found.label : (req.action || '-')
|
||||||
|
}
|
||||||
|
|
||||||
|
function operatorOf(row) {
|
||||||
|
return parseReq(row).operator || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
function productCodeOf(row) {
|
||||||
|
const keys = parseReq(row).bizKeys || {}
|
||||||
|
return keys.productCode || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
function countryOf(row) {
|
||||||
|
const keys = parseReq(row).bizKeys || {}
|
||||||
|
if (keys.countryCode && keys.countryName) return keys.countryName + ' (' + keys.countryCode + ')'
|
||||||
|
return keys.countryCode || keys.countryName || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
function changesOf(row) {
|
||||||
|
const req = parseReq(row)
|
||||||
|
return Array.isArray(req.changes) ? req.changes : []
|
||||||
|
}
|
||||||
|
|
||||||
|
function statusLabel(status) {
|
||||||
|
const found = statusOptions.find(item => item.value === status)
|
||||||
|
if (found) return found.label
|
||||||
|
return status === 'FAIL' ? '失败' : '成功'
|
||||||
|
}
|
||||||
|
|
||||||
|
function statusTag(status) {
|
||||||
|
return status === 'FAIL' ? 'danger' : 'success'
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleView(row) {
|
||||||
|
drawerTitle.value = '价格日志 #' + (row.bizId || row.docId)
|
||||||
|
open.value = true
|
||||||
|
loading.value = true
|
||||||
|
detail.value = null
|
||||||
|
getPriceLog(row.docId).then(res => {
|
||||||
|
detail.value = res.data || row
|
||||||
|
}).finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatJson(val) {
|
||||||
|
if (val === null || val === undefined || val === '') return '无数据'
|
||||||
|
if (typeof val === 'object') {
|
||||||
|
try { return JSON.stringify(val, null, 2) } catch (e) { return String(val) }
|
||||||
|
}
|
||||||
|
try { return JSON.stringify(JSON.parse(val), null, 2) } catch (e) { return String(val) }
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyJson(val) {
|
||||||
|
const text = formatJson(val)
|
||||||
|
const done = () => ElMessage({ message: '已复制', type: 'success', duration: 1500 })
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
navigator.clipboard.writeText(text).then(done)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const ta = document.createElement('textarea')
|
||||||
|
ta.value = text
|
||||||
|
document.body.appendChild(ta)
|
||||||
|
ta.select()
|
||||||
|
document.execCommand('copy')
|
||||||
|
document.body.removeChild(ta)
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.mb12 { margin-bottom: 12px; }
|
||||||
|
.err-text { color: #f56c6c; word-break: break-all; }
|
||||||
|
.change-panel {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
border: 1px solid #e8ecf0;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.change-panel__head {
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #606266;
|
||||||
|
background: #fafbfc;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
.json-panel {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background: #f7f9fb;
|
||||||
|
border: 1px solid #e8ecf0;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.json-panel__head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #606266;
|
||||||
|
background: #fafbfc;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
.json-panel .code-pre {
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 14px;
|
||||||
|
max-height: 280px;
|
||||||
|
overflow: auto;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user