套餐启用增加生效时间

This commit is contained in:
wuweihua
2026-09-17 14:42:48 +08:00
parent 51c8013cd9
commit f3ef2df949
25 changed files with 684 additions and 287 deletions
@@ -1,21 +1,23 @@
package com.ruoyi.web.controller.api;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.price.domain.vo.TmsPriceBillRequest;
import com.ruoyi.price.domain.vo.TmsPriceQuoteRequest;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.price.search.EsBizLogSupport;
import com.ruoyi.price.search.EsLogType;
import com.ruoyi.price.search.IBillSearchStore;
import com.ruoyi.web.controller.price.BillingController;
/**
* Persist validation failures of quote/bill APIs to Elasticsearch.
* Persist quote/bill API failures to Elasticsearch (validation, JSON parse, business, unexpected).
* Uses {@link EsBizLogSupport#saveApiFail} so service/controller can also call without duplicate docs.
*/
@Order(0)
@RestControllerAdvice(assignableTypes = { TmsPriceController.class, BillingController.class })
@@ -25,37 +27,61 @@ public class PriceSyncEsLogAdvice
private IBillSearchStore billSearchStore;
@ExceptionHandler(MethodArgumentNotValidException.class)
public AjaxResult handleValid(MethodArgumentNotValidException e)
public AjaxResult handleValid(MethodArgumentNotValidException e, HttpServletRequest request)
{
String message = e.getBindingResult().getFieldError() == null
? e.getMessage()
: e.getBindingResult().getFieldError().getDefaultMessage();
saveFail(e.getBindingResult().getTarget(), message);
saveFail(request, e.getBindingResult().getTarget(), message);
return AjaxResult.error(message);
}
@ExceptionHandler(BindException.class)
public AjaxResult handleBind(BindException e)
public AjaxResult handleBind(BindException e, HttpServletRequest request)
{
String message = e.getAllErrors().isEmpty() ? e.getMessage() : e.getAllErrors().get(0).getDefaultMessage();
saveFail(e.getTarget(), message);
saveFail(request, e.getTarget(), message);
return AjaxResult.error(message);
}
private void saveFail(Object target, String message)
@ExceptionHandler(HttpMessageNotReadableException.class)
public AjaxResult handleNotReadable(HttpMessageNotReadableException e, HttpServletRequest request)
{
if (target instanceof TmsPriceBillRequest)
String message = EsBizLogSupport.errorText(e);
saveFail(request, null, message);
return AjaxResult.error(message);
}
@ExceptionHandler(ServiceException.class)
public AjaxResult handleService(ServiceException e, HttpServletRequest request)
{
saveFail(request, null, e);
Integer code = e.getCode();
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
}
@ExceptionHandler(Exception.class)
public AjaxResult handleAny(Exception e, HttpServletRequest request)
{
saveFail(request, null, e);
return AjaxResult.error(EsBizLogSupport.errorText(e));
}
private void saveFail(HttpServletRequest request, Object boundTarget, Throwable e)
{
if (!EsBizLogSupport.isPriceSyncWriteApi(request))
{
TmsPriceBillRequest request = (TmsPriceBillRequest) target;
EsBizLogSupport.saveFail(billSearchStore, EsLogType.BILL, EsBizLogSupport.billFailBizId(request), request,
message);
return;
}
if (target instanceof TmsPriceQuoteRequest)
EsBizLogSupport.saveApiFail(billSearchStore, request, boundTarget, e);
}
private void saveFail(HttpServletRequest request, Object boundTarget, String message)
{
if (!EsBizLogSupport.isPriceSyncWriteApi(request))
{
TmsPriceQuoteRequest request = (TmsPriceQuoteRequest) target;
EsBizLogSupport.saveFail(billSearchStore, EsLogType.QUOTE, EsBizLogSupport.quoteFailBizId(request),
request, message);
return;
}
EsBizLogSupport.saveApiFail(billSearchStore, request, boundTarget, message);
}
}
@@ -1,5 +1,7 @@
package com.ruoyi.web.controller.price;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -24,6 +26,7 @@ import com.ruoyi.price.domain.PrcCustomerPriceSet;
import com.ruoyi.price.domain.PrcPriceSet;
import com.ruoyi.price.domain.PrcPriceSetDetail;
import com.ruoyi.price.domain.PrcPriceSetSaveTask;
import com.ruoyi.price.domain.PrcPriceSetVersion;
import com.ruoyi.price.service.IPrcPriceSetService;
/**
@@ -124,9 +127,10 @@ public class PriceSetController extends BaseController
@PreAuthorize("@ss.hasPermi('price:set:edit')")
@Log(title = "Price set version activate", businessType = BusinessType.UPDATE)
@PutMapping("/version/activate/{psvId}")
public AjaxResult activateVersion(@PathVariable Long psvId)
public AjaxResult activateVersion(@PathVariable Long psvId, @RequestBody(required = false) PrcPriceSetVersion body)
{
return toAjax(priceSetService.activateVersion(psvId, getUsername()));
Date effectiveTime = body == null ? null : body.getEffectiveTime();
return toAjax(priceSetService.activateVersion(psvId, effectiveTime, getUsername()));
}
@PreAuthorize("@ss.hasPermi('price:set:add')")
@@ -1,40 +0,0 @@
package com.ruoyi.web.controller.price;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.price.task.BmsStatusRefreshTask;
/**
* 状态自动刷新 - 手动触发入口
*
* <p>日常由 BmsStatusRefreshTask 每天 02:00 跑,特殊情况可手动触发。
*
* @author ruoyi
*/
@RestController
@RequestMapping("/price/status")
public class PriceStatusController extends BaseController
{
@Autowired
private BmsStatusRefreshTask refreshTask;
/**
* 立即刷新 bms_product / bms_product_country 的 status 字段
*/
@PreAuthorize("@ss.hasPermi('price:product:edit')")
@PostMapping("/refresh")
public AjaxResult refresh()
{
int[] counts = refreshTask.refreshNow();
String msg = MessageUtils.message("price.status.refresh.success",
String.valueOf(counts[0]), String.valueOf(counts[1]),
String.valueOf(counts.length > 2 ? counts[2] : 0));
return success(msg);
}
}
@@ -126,6 +126,8 @@ price.quote.freightMissing2=产品默认运费或挂号费为空
price.quote.freightMissing3=运费为空
price.quote.requestBodyRequired=请求体为空
price.quote.customerIdRequired=客户ID为空
price.quote.customerCodeRequired=客户代码不能为空
price.quote.customerCodeNotFound=客户代码不存在
price.quote.productCodeRequired=产品代码为空
price.quote.countryRequired=国家代码或国家名称为空
price.quote.weightInvalid=重量必须大于0
@@ -135,8 +137,6 @@ price.quote.noCustomerPackageOverride=没有客户套餐覆盖,使用产品默
price.quote.quoteIdRequired=报价ID为空
price.quote.hitCustomerFixedPackageDetail=命中客户套餐固定价格明细
# ---- 状态自动刷新 ----
price.status.refresh.success=状态刷新完成:bms_product 更新 {0} 行,bms_product_country 更新 {1} 行,价格套餐版本 {2} 套
# receivable bill
price.bill.orderNoRequired=订单号为空
price.bill.billIdRequired=计费ID为空
@@ -147,6 +147,7 @@ price.set.version.effectiveTime.empty=版本生效时间不能为空
price.set.version.notExists=套餐版本不存在
price.set.version.activate.statusNotAllowed=仅草稿版本可启动
price.set.version.delete.statusNotAllowed=仅草稿版本可删除
price.set.version.copy.draftExists=已有草稿版本,请先启动或删除后再复制
price.set.save.task.notExists=保存任务不存在或已过期
price.set.library.empty=产品库无可用价格明细,请检查产品国家配置
price.set.detail.duplicate.fixed=产品{0} 国家{1} 重量段{2} {3}(共{4}条)