编码规则

localizer
lzq 2025-10-30 14:14:45 +08:00
parent ff2df428fd
commit 21247d629f
13 changed files with 106 additions and 35 deletions

View File

@ -29,11 +29,6 @@ public class AddSnConfigParam implements Constrained {
@NotBlank(message = "编码名称不能为空") @NotBlank(message = "编码名称不能为空")
private String sncode; private String sncode;
/**
*
*/
@NotBlank(message = "示例不能为空")
private String example;
/** /**
* *
*/ */

View File

@ -84,6 +84,7 @@ public class IncSnService extends ServiceImpl<IncSnMapper, IncSnEntity> implemen
if (val == maxVal) { if (val == maxVal) {
Boolean allowOverflow = incCodeEntity.getAllowOverflow(); Boolean allowOverflow = incCodeEntity.getAllowOverflow();
if (allowOverflow == null) allowOverflow = Boolean.TRUE;
if (allowOverflow) { if (allowOverflow) {
newVal = incCodeEntity.getInitialVal(); newVal = incCodeEntity.getInitialVal();
} else { } else {
@ -92,9 +93,13 @@ public class IncSnService extends ServiceImpl<IncSnMapper, IncSnEntity> implemen
} }
RollbackMode rollback = incCodeEntity.getRollback(); RollbackMode rollback = incCodeEntity.getRollback();
if (rollback == null) rollback = RollbackMode.Wu;
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
LocalDateTime lastTime = incCodeEntity.getLastTime(); LocalDateTime lastTime = incCodeEntity.getLastTime();
if (lastTime == null) {
lastTime = now;
}
switch (rollback) { switch (rollback) {
case Wu: { case Wu: {
@ -181,9 +186,9 @@ public class IncSnService extends ServiceImpl<IncSnMapper, IncSnEntity> implemen
Assert.notBlank(pici, () -> Exceptions.exception("批次号不能为空")); Assert.notBlank(pici, () -> Exceptions.exception("批次号不能为空"));
String lastPici = incCodeEntity.getLastPici(); String lastPici = incCodeEntity.getLastPici();
if (pici.equals(lastPici)) { if (pici.equals(lastPici)) {
newVal = incCodeEntity.getInitialVal();
} else {
newVal = val + incCodeEntity.getStep(); newVal = val + incCodeEntity.getStep();
} else {
newVal = incCodeEntity.getInitialVal();
} }
} }
break; break;

View File

@ -28,11 +28,6 @@ public class ModifySnConfigParam implements Constrained {
* *
*/ */
private String sncode; private String sncode;
/**
*
*/
private String example;
/** /**
* *
*/ */

View File

@ -32,8 +32,15 @@ public class SnConfigController {
} }
@GetMapping("/next") @GetMapping("/next")
public R<?> next(@RequestParam(required = false, defaultValue = "Default") String sncode) { public R<?> next(@RequestParam(required = false, defaultValue = "Default") String sncode,
return R.success(SnUtil.next(sncode)); @RequestParam(required = false) String pici) {
return R.success(SnUtil.next(sncode, pici));
}
@GetMapping("/reset")
public R<?> reset(@RequestParam("sncode") String sncode) {
snConfigService.reset(sncode);
return R.success();
} }
/** /**

View File

@ -53,11 +53,13 @@ public class SnConfigService extends ServiceImpl<SnConfigMapper, SnConfigEntity>
List<HashMap<String, Object>> configList = addSnConfigParam.getConfig(); List<HashMap<String, Object>> configList = addSnConfigParam.getConfig();
Tuple2<List<SectionConfig>, List<IncSnEntity>> tuple2 = resolveConfig(configList); Tuple2<List<SectionConfig>, List<IncSnEntity>> tuple2 = resolveConfig(configList);
List<SectionConfig> configs = tuple2.get_0();
String example = configs.stream().map(SectionConfig::genExample).collect(Collectors.joining());
this.save(new SnConfigEntity() this.save(new SnConfigEntity()
.setSnname(addSnConfigParam.getSnname()) .setSnname(addSnConfigParam.getSnname())
.setSncode(sncode) .setSncode(sncode)
.setExample(addSnConfigParam.getExample()) .setExample(example)
.setConfig(tuple2.get_0()) .setConfig(configs)
.setMemo(addSnConfigParam.getMemo()) .setMemo(addSnConfigParam.getMemo())
); );
@ -125,12 +127,13 @@ public class SnConfigService extends ServiceImpl<SnConfigMapper, SnConfigEntity>
oldIncSnEntityList = incSnService.list(Wrappers.lambdaQuery(IncSnEntity.class).in(IncSnEntity::getCode, oldIncSectionConfigCodeList)); oldIncSnEntityList = incSnService.list(Wrappers.lambdaQuery(IncSnEntity.class).in(IncSnEntity::getCode, oldIncSectionConfigCodeList));
} }
modifyIncSnSectionConfig(oldIncSnEntityList, tuple2.get_1()); modifyIncSnSectionConfig(oldIncSnEntityList, tuple2.get_1());
List<SectionConfig> configs = tuple2.get_0();
String example = configs.stream().map(SectionConfig::genExample).collect(Collectors.joining());
this.updateById(new SnConfigEntity() this.updateById(new SnConfigEntity()
.setId(id) .setId(id)
.setSnname(modifySnConfigParam.getSnname()) .setSnname(modifySnConfigParam.getSnname())
.setSncode(modifySnConfigParam.getSncode()) .setSncode(modifySnConfigParam.getSncode())
.setExample(modifySnConfigParam.getExample()) .setExample(example)
.setConfig(tuple2.get_0()) .setConfig(tuple2.get_0())
.setMemo(modifySnConfigParam.getMemo()) .setMemo(modifySnConfigParam.getMemo())
); );
@ -206,4 +209,27 @@ public class SnConfigService extends ServiceImpl<SnConfigMapper, SnConfigEntity>
return PageResult.of(page.convert(it -> BeanUtil.copyProperties(it, SearchSnConfigResult.class))); return PageResult.of(page.convert(it -> BeanUtil.copyProperties(it, SearchSnConfigResult.class)));
} }
@Transactional(rollbackFor = Exception.class)
public void reset(String sncode) {
SnConfigEntity configEntity = this.getOne(Wrappers.lambdaQuery(SnConfigEntity.class).eq(SnConfigEntity::getSncode, sncode));
Assert.notNull(configEntity, () -> Exceptions.clierr("规则不存在"));
List<SectionConfig> config = configEntity.getConfig();
List<String> codes = config.stream().filter(it -> it instanceof IncSectionConfig)
.map(it -> ((IncSectionConfig) it).getCode())
.collect(Collectors.toList());
if (CollUtil.isEmpty(codes)) return;
List<IncSnEntity> incSnEntityList = incSnService
.list(Wrappers.lambdaQuery(IncSnEntity.class).in(IncSnEntity::getCode, codes))
.stream().map(it -> BeanUtil.copyProperties(it, IncSnEntity.class)
.setVal(it.getInitialVal())
.setLastTime(null)
.setLastPici(null)
)
.collect(Collectors.toList());
incSnService.remove(Wrappers.lambdaQuery(IncSnEntity.class).in(IncSnEntity::getCode, codes));
incSnService.saveBatch(incSnEntityList);
}
} }

View File

@ -21,6 +21,11 @@ public class FixedSectionConfig implements SectionConfig {
private String value; private String value;
@Override
public String genExample() {
return value;
}
@Override @Override
public ISnSection section() { public ISnSection section() {
return new FixedSection(value); return new FixedSection(value);

View File

@ -2,6 +2,7 @@ package com.njzscloud.common.sn.support;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.njzscloud.common.core.ex.Exceptions; import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.ienum.Dict; import com.njzscloud.common.core.ienum.Dict;
import com.njzscloud.common.sn.contant.PadMode; import com.njzscloud.common.sn.contant.PadMode;
@ -51,6 +52,13 @@ public class IncSectionConfig implements SectionConfig {
*/ */
private Boolean allowOverflow; private Boolean allowOverflow;
@Override
public String genExample() {
return padMode == PadMode.Zuo ? StrUtil.padPre(initialVal.toString(), padLen, padVal) :
padMode == PadMode.You ? StrUtil.padAfter(initialVal.toString(), padLen, padVal) :
initialVal.toString();
}
@Override @Override
public ISnSection section() { public ISnSection section() {
return new IncSection(code, step, initialVal, padMode, padVal, padLen); return new IncSection(code, step, initialVal, padMode, padVal, padLen);
@ -61,6 +69,9 @@ public class IncSectionConfig implements SectionConfig {
code = MapUtil.getStr(config, "code"); code = MapUtil.getStr(config, "code");
step = MapUtil.getInt(config, "step"); step = MapUtil.getInt(config, "step");
initialVal = MapUtil.getInt(config, "initialVal"); initialVal = MapUtil.getInt(config, "initialVal");
rollback = Dict.parse(MapUtil.getStr(config, "rollback"), RollbackMode.values());
if (rollback == null) rollback = RollbackMode.Wu;
allowOverflow = MapUtil.getBool(config, "allowOverflow", Boolean.TRUE);
padMode = Dict.parse(MapUtil.getStr(config, "padMode"), PadMode.values()); padMode = Dict.parse(MapUtil.getStr(config, "padMode"), PadMode.values());
if (padMode == null) padMode = PadMode.Wu; if (padMode == null) padMode = PadMode.Wu;
padVal = MapUtil.getStr(config, "padVal"); padVal = MapUtil.getStr(config, "padVal");

View File

@ -2,6 +2,7 @@ package com.njzscloud.common.sn.support;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import com.njzscloud.common.core.ex.Exceptions; import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.ienum.Dict; import com.njzscloud.common.core.ienum.Dict;
import com.njzscloud.common.sn.contant.RandomMode; import com.njzscloud.common.sn.contant.RandomMode;
@ -34,6 +35,18 @@ public class RandomSectionConfig implements SectionConfig {
*/ */
private Integer nanoIdSize; private Integer nanoIdSize;
@Override
public String genExample() {
switch (randomMode) {
case UUID:
return IdUtil.simpleUUID();
case NanoId:
return nanoIdSize == null ? IdUtil.nanoId() : IdUtil.nanoId(nanoIdSize);
default:
return workerId == null || datacenterId == null ? IdUtil.getSnowflakeNextIdStr() : IdUtil.getSnowflake(workerId, datacenterId).nextIdStr();
}
}
@Override @Override
public ISnSection section() { public ISnSection section() {
return new RandomSection(randomMode, workerId, datacenterId, nanoIdSize); return new RandomSection(randomMode, workerId, datacenterId, nanoIdSize);

View File

@ -12,6 +12,8 @@ public interface SectionConfig {
*/ */
SnSection getSectionName(); SnSection getSectionName();
String genExample();
/** /**
* *
*/ */

View File

@ -40,8 +40,12 @@ public final class SnUtil {
return next("Default"); return next("Default");
} }
public static synchronized String next(String sncode) { public static String next(String sncode) {
return next(sncode, null);
}
public static synchronized String next(String sncode, String pici) {
Assert.notBlank(sncode, () -> Exceptions.clierr("未指定编码规则")); Assert.notBlank(sncode, () -> Exceptions.clierr("未指定编码规则"));
return SN_CONFIG_SERVICE.getSn(sncode).next(); return SN_CONFIG_SERVICE.getSn(sncode).next(pici);
} }
} }

View File

@ -1,5 +1,6 @@
package com.njzscloud.common.sn.support; package com.njzscloud.common.sn.support;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
@ -10,6 +11,7 @@ import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.Date;
import java.util.Map; import java.util.Map;
@Getter @Getter
@ -31,6 +33,11 @@ public class TimeSectionConfig implements SectionConfig {
*/ */
private Integer unit; private Integer unit;
@Override
public String genExample() {
return timestamp ? new Date().getTime() / unit + "" : DateUtil.format(new Date(), pattern);
}
@Override @Override
public ISnSection section() { public ISnSection section() {
return new TimeSection(pattern, timestamp, unit); return new TimeSection(pattern, timestamp, unit);

View File

@ -34,7 +34,7 @@ public class OrderInfoController {
* *
*/ */
@PostMapping("/add") @PostMapping("/add")
public R<?> add(@RequestBody AddOrderInfoParam addOrderInfoParam) { public synchronized R<?> add(@RequestBody AddOrderInfoParam addOrderInfoParam) {
OrderCategory orderCategory = addOrderInfoParam.getOrderCategory(); OrderCategory orderCategory = addOrderInfoParam.getOrderCategory();
Assert.isTrue(orderCategory == OrderCategory.PuTong Assert.isTrue(orderCategory == OrderCategory.PuTong
|| orderCategory == OrderCategory.DuanBoChu || orderCategory == OrderCategory.DuanBoChu

View File

@ -109,6 +109,7 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
* *
*/ */
public void add(AddOrderInfoParam addOrderInfoParam, String orderSn) { public void add(AddOrderInfoParam addOrderInfoParam, String orderSn) {
Assert.isFalse(this.exists(Wrappers.<OrderInfoEntity>lambdaQuery().eq(OrderInfoEntity::getSn, addOrderInfoParam.getSn())), () -> Exceptions.exception("订单创建失败,订单号重复"));
AddOrderCargoPlaceParam cargoPlace = addOrderInfoParam.getCargoPlace(); AddOrderCargoPlaceParam cargoPlace = addOrderInfoParam.getCargoPlace();
long cargoPlaceId = orderCargoPlaceService.add(cargoPlace); long cargoPlaceId = orderCargoPlaceService.add(cargoPlace);
Long userId = SecurityUtil.currentUserId(); Long userId = SecurityUtil.currentUserId();
@ -1090,7 +1091,7 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
/** /**
* *
* / * /
* *
* @param item * @param item
* @return * @return
*/ */
@ -1103,13 +1104,13 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
// 1. 将数量(公斤)转换为吨 // 1. 将数量(公斤)转换为吨
BigDecimal actualWeight = new BigDecimal(item.getQuantity() == null ? 0 : item.getQuantity()) BigDecimal actualWeight = new BigDecimal(item.getQuantity() == null ? 0 : item.getQuantity())
.divide(new BigDecimal("1000"), 6, BigDecimal.ROUND_HALF_UP); .divide(new BigDecimal("1000"), 6, BigDecimal.ROUND_HALF_UP);
// 2. 获取弹性计费参数 // 2. 获取弹性计费参数
BigDecimal basicWeight = item.getBasicWeight(); BigDecimal basicWeight = item.getBasicWeight();
BigDecimal basicPrice = item.getBasicPrice(); BigDecimal basicPrice = item.getBasicPrice();
BigDecimal everyWeight = item.getEveryWeight(); BigDecimal everyWeight = item.getEveryWeight();
BigDecimal everyPrice = item.getEveryPrice(); BigDecimal everyPrice = item.getEveryPrice();
// 3. 计算总金额 // 3. 计算总金额
if (actualWeight.compareTo(basicWeight) <= 0) { if (actualWeight.compareTo(basicWeight) <= 0) {
// 实际重量小于等于基础磅重,使用基础价格 // 实际重量小于等于基础磅重,使用基础价格
@ -1135,33 +1136,33 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
/** /**
* *
* *
* @param item * @param item
*/ */
private void calculateAndSetItemMoney(OrderExpenseItemsEntity item) { private void calculateAndSetItemMoney(OrderExpenseItemsEntity item) {
// 计算总金额 // 计算总金额
BigDecimal totalMoney = calculateItemTotalMoney(item); BigDecimal totalMoney = calculateItemTotalMoney(item);
// settle_money = total_money + discount_money + revise_moneydiscount、revise 可为正负) // settle_money = total_money + discount_money + revise_moneydiscount、revise 可为正负)
BigDecimal discount = item.getDiscountMoney() == null ? BigDecimal.ZERO : item.getDiscountMoney(); BigDecimal discount = item.getDiscountMoney() == null ? BigDecimal.ZERO : item.getDiscountMoney();
BigDecimal revise = item.getReviseMoney() == null ? BigDecimal.ZERO : item.getReviseMoney(); BigDecimal revise = item.getReviseMoney() == null ? BigDecimal.ZERO : item.getReviseMoney();
BigDecimal settle = totalMoney.add(discount).add(revise); BigDecimal settle = totalMoney.add(discount).add(revise);
item.setTotalMoney(totalMoney).setSettleMoney(settle); item.setTotalMoney(totalMoney).setSettleMoney(settle);
} }
/** /**
* *
* *
* @param orderId ID * @param orderId ID
* @param items * @param items
*/ */
private void updateOrderTotalMoney(Long orderId, List<OrderExpenseItemsEntity> items) { private void updateOrderTotalMoney(Long orderId, List<OrderExpenseItemsEntity> items) {
BigDecimal totalDiscountMoney = BigDecimal.ZERO; BigDecimal totalDiscountMoney = BigDecimal.ZERO;
BigDecimal totalReviseMoney = BigDecimal.ZERO; BigDecimal totalReviseMoney = BigDecimal.ZERO;
BigDecimal totalSettleMoney = BigDecimal.ZERO; BigDecimal totalSettleMoney = BigDecimal.ZERO;
BigDecimal totalTotalMoney = BigDecimal.ZERO; BigDecimal totalTotalMoney = BigDecimal.ZERO;
// 汇总各项金额 // 汇总各项金额
for (OrderExpenseItemsEntity item : items) { for (OrderExpenseItemsEntity item : items) {
BigDecimal discount = item.getDiscountMoney() == null ? BigDecimal.ZERO : item.getDiscountMoney(); BigDecimal discount = item.getDiscountMoney() == null ? BigDecimal.ZERO : item.getDiscountMoney();
@ -1185,16 +1186,16 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
/** /**
* *
* *
* @param orderId ID * @param orderId ID
* @param items * @param items
*/ */
private void calculateItemsAndUpdateOrder(Long orderId, List<OrderExpenseItemsEntity> items) { private void calculateItemsAndUpdateOrder(Long orderId, List<OrderExpenseItemsEntity> items) {
// 计算各付费项金额 // 计算各付费项金额
for (OrderExpenseItemsEntity item : items) { for (OrderExpenseItemsEntity item : items) {
calculateAndSetItemMoney(item); calculateAndSetItemMoney(item);
} }
// 更新订单汇总金额 // 更新订单汇总金额
updateOrderTotalMoney(orderId, items); updateOrderTotalMoney(orderId, items);
} }
@ -1203,14 +1204,14 @@ public class OrderInfoService extends ServiceImpl<OrderInfoMapper, OrderInfoEnti
List<OrderExpenseItemsEntity> extraItems = orderExpenseItemsService.list(Wrappers.lambdaQuery(OrderExpenseItemsEntity.class) List<OrderExpenseItemsEntity> extraItems = orderExpenseItemsService.list(Wrappers.lambdaQuery(OrderExpenseItemsEntity.class)
.eq(OrderExpenseItemsEntity::getOrderId, orderId) .eq(OrderExpenseItemsEntity::getOrderId, orderId)
.eq(OrderExpenseItemsEntity::getDeleted, Boolean.FALSE)); .eq(OrderExpenseItemsEntity::getDeleted, Boolean.FALSE));
// 更新数量:按车计费数量=1否则=称重数量 // 更新数量:按车计费数量=1否则=称重数量
for (OrderExpenseItemsEntity item : extraItems) { for (OrderExpenseItemsEntity item : extraItems) {
item.setQuantity(MoneyStrategy.Che.getVal().equals(item.getMoneyStrategy()) ? 1 : settleWeight); item.setQuantity(MoneyStrategy.Che.getVal().equals(item.getMoneyStrategy()) ? 1 : settleWeight);
// 重新计算金额totalMoney、settleMoney // 重新计算金额totalMoney、settleMoney
calculateAndSetItemMoney(item); calculateAndSetItemMoney(item);
} }
// 批量更新付费项包含quantity和所有金额字段 // 批量更新付费项包含quantity和所有金额字段
orderExpenseItemsService.updateBatchById(extraItems); orderExpenseItemsService.updateBatchById(extraItems);