|
|
@@ -62,8 +62,8 @@ public class SalesPriceController {
|
|
|
@Transactional
|
|
|
public AjaxResult add(@RequestBody SalesPrice price, HttpServletRequest request) throws Exception {
|
|
|
String orgId = tokenService.getLoginOrgId(request);
|
|
|
- // 新增时后台统一生成价格单编号:P + 当前时间后一天yyyyMMdd
|
|
|
- price.setPriceNum(generatePriceNum());
|
|
|
+ // 新增时后台统一生成价格单编号:确保组织内唯一
|
|
|
+ price.setPriceNum(nextAvailablePriceNum(orgId));
|
|
|
validateBeforeSave(price, orgId, true);
|
|
|
price.setOrgId(orgId);
|
|
|
price.setDelFlag("0");
|
|
|
@@ -216,6 +216,18 @@ public class SalesPriceController {
|
|
|
return success(items);
|
|
|
}
|
|
|
|
|
|
+ @ApiOperation("获取新增价格页面数据")
|
|
|
+ @PreAuthorize("@ss.hasPermi('base:price:add')")
|
|
|
+ @PostMapping("/getAddPageData")
|
|
|
+ public AjaxResult getAddPageData(HttpServletRequest request) {
|
|
|
+ // 执行日期/失效日期均默认取“当前日期后一天”
|
|
|
+ String tomorrow = LocalDate.now().plusDays(1).format(DateTimeFormatter.ISO_LOCAL_DATE);
|
|
|
+ Map<String, Object> data = new HashMap<String, Object>();
|
|
|
+ data.put("effectiveDate", tomorrow);
|
|
|
+ data.put("expireDate", tomorrow);
|
|
|
+ return success(data);
|
|
|
+ }
|
|
|
+
|
|
|
@ApiOperation("价格管理导出")
|
|
|
@PreAuthorize("@ss.hasPermi('base:price:export')")
|
|
|
@PostMapping("/export")
|
|
|
@@ -308,6 +320,10 @@ public class SalesPriceController {
|
|
|
if (price == null) {
|
|
|
throw new Exception("参数不能为空");
|
|
|
}
|
|
|
+ if (StringUtils.isBlank(price.getPriceType())) {
|
|
|
+ throw new Exception("价格类型不能为空");
|
|
|
+ }
|
|
|
+ price.setPriceType(price.getPriceType().trim());
|
|
|
if (!isAdd && StringUtils.isBlank(price.getPriceNum())) {
|
|
|
throw new Exception("价格单编号不能为空");
|
|
|
}
|
|
|
@@ -317,9 +333,25 @@ public class SalesPriceController {
|
|
|
if (price.getExpireDate().before(price.getEffectiveDate())) {
|
|
|
throw new Exception("失效日期不能早于执行日期");
|
|
|
}
|
|
|
+
|
|
|
+ // 同一价格类型 + 同一执行日期(未删除)仅允许一条主表记录
|
|
|
+ // effective_date 为 date 类型,直接按日期精确匹配
|
|
|
+ QueryWrapper<SalesPrice> effectiveWrapper = new QueryWrapper<SalesPrice>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .eq("price_type", price.getPriceType())
|
|
|
+ .eq("effective_date", price.getEffectiveDate());
|
|
|
+ if (!isAdd && price.getId() != null) {
|
|
|
+ effectiveWrapper.ne("id", price.getId());
|
|
|
+ }
|
|
|
+ if (salesPriceService.count(effectiveWrapper) > 0) {
|
|
|
+ throw new Exception("该价格类型在执行日期已存在价格单");
|
|
|
+ }
|
|
|
+
|
|
|
QueryWrapper<SalesPrice> numWrapper = new QueryWrapper<SalesPrice>()
|
|
|
.eq("org_id", orgId)
|
|
|
.eq("price_num", price.getPriceNum())
|
|
|
+ .eq("price_type", price.getPriceType())
|
|
|
.eq("del_flag", "0");
|
|
|
if (!isAdd && price.getId() != null) {
|
|
|
numWrapper.ne("id", price.getId());
|
|
|
@@ -340,23 +372,43 @@ public class SalesPriceController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private String generatePriceNum() {
|
|
|
- String ymd = LocalDate.now().plusDays(1).format(DateTimeFormatter.BASIC_ISO_DATE);
|
|
|
- return "P" + ymd;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
- * 生成组织内未占用的价格单编号:P+次日yyyyMMdd,若已存在则依次尝试 P...-1、P...-2…
|
|
|
+ * 生成组织内未占用的价格单编号:
|
|
|
+ * P + 次日yyyyMMdd + 5位递增序号(不足补0,从00001开始)
|
|
|
*/
|
|
|
private String nextAvailablePriceNum(String orgId) throws Exception {
|
|
|
String ymd = LocalDate.now().plusDays(1).format(DateTimeFormatter.BASIC_ISO_DATE);
|
|
|
String prefix = "P" + ymd;
|
|
|
- for (int n = 0; n < 10000; n++) {
|
|
|
- String candidate = n == 0 ? prefix : prefix + "-" + n;
|
|
|
- if (salesPriceService.count(new QueryWrapper<SalesPrice>()
|
|
|
+
|
|
|
+ // 先取已存在最大后缀,作为起始序号(避免每次都从 00001 开始扫描)
|
|
|
+ SalesPrice last = salesPriceService.getOne(new QueryWrapper<SalesPrice>()
|
|
|
+ .eq("org_id", orgId)
|
|
|
+ .eq("del_flag", "0")
|
|
|
+ .like("price_num", prefix)
|
|
|
+ .orderByDesc("price_num")
|
|
|
+ .last("limit 1"));
|
|
|
+
|
|
|
+ int startSeq = 1;
|
|
|
+ if (last != null && StringUtils.isNotBlank(last.getPriceNum())) {
|
|
|
+ String pn = last.getPriceNum().trim();
|
|
|
+ // pn 应为:PyyyyMMdd + 5位数字
|
|
|
+ if (pn.startsWith(prefix) && pn.length() == prefix.length() + 5) {
|
|
|
+ String suffix = pn.substring(prefix.length());
|
|
|
+ try {
|
|
|
+ startSeq = Integer.parseInt(suffix) + 1;
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ startSeq = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int seq = startSeq; seq <= 99999; seq++) {
|
|
|
+ String candidate = prefix + String.format("%05d", seq);
|
|
|
+ long occupied = salesPriceService.count(new QueryWrapper<SalesPrice>()
|
|
|
.eq("org_id", orgId)
|
|
|
.eq("price_num", candidate)
|
|
|
- .eq("del_flag", "0")) == 0) {
|
|
|
+ .eq("del_flag", "0"));
|
|
|
+ if (occupied == 0) {
|
|
|
return candidate;
|
|
|
}
|
|
|
}
|