模版方法
入口调用:
// 注册最终实现层
@Autowired
ReceiptYcOrderHandler receiptYcHandler;
@PostMapping("/receipt")
public R<Boolean> receipt() {
try {
receiptYcHandler.doHander();
return R.success();
}catch (Exception e){
return R.error();
}
}
顶层接口:
// 顶层
public interface OrderHandler {
public void doHander();
}
顶层实现类:
@Slf4j
public abstract class AbstractOrderHandler<S, T> implements OrderHandler {
// 顶层接口实现
@Override
public void doHander() {
List<S> originalOrderList = this.queryOriginalOrderList();
if(CollectionUtils.isNotEmpty(originalOrderList)) {
for(S originalOrder : originalOrderList) {
try {
doHandler(originalOrder);
} catch (Exception e) {
log.error("handler order error", e);
executeError(originalOrder, e);
}
}
}
}
/**
* 执行单个数据的处理操作
* @param originalOrder
* @return
*/
public void doHandler(S originalOrderInfo) {
StopWatch stopWatch = new StopWatch("订单性能监控开始,当前订单信息:" + JSONObject.toJSONString(originalOrderInfo));
try {
/**
* 数据准备
*/
stopWatch.start("准备待处理正式数据");
T formalOrderInfo = prepare(originalOrderInfo);
stopWatch.stop();
/**
* 前置校验
*/
stopWatch.start("前置校验");
boolean checkResult = preCheck(formalOrderInfo);
stopWatch.stop();
if(!checkResult) {
deleteOriginal(formalOrderInfo);
return;
}
/**
* 数据补充,转换
*/
stopWatch.start("补充填充额外数据");
replenishOrder(formalOrderInfo);
stopWatch.stop();
if (formalOrderInfo != null) {
/**
* 保存db前置处理
*/
stopWatch.start("保存数据库前置处理");
doBeforeSaveDb(formalOrderInfo);
stopWatch.stop();
/**
* 执行数据库保存操作
*/
stopWatch.start("保存数据");
Boolean executeResult = transactionTemplate.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
/**
* 保存db
*/
boolean doSaveInTransactional = doSaveInTransactional(formalOrderInfo);
if(doSaveInTransactional) {
/**
* 保存数据成功后删除临时数据
*/
deleteOriginal(formalOrderInfo);
}
return doSaveInTransactional;
}
});
stopWatch.stop();
if (executeResult) {
/**
* 保存db完成后置处理
*/
stopWatch.start("保存后置处理");
doAfterSaveDb(formalOrderInfo);
stopWatch.stop();
}
}
} finally {
log.info(stopWatch.prettyPrint());
}
}
/**
* 查询待处理数据---抽象
* @param
* @return
*/
public abstract List<S> queryOriginalOrderList();
/**
* 准备工作
* @param originalOrder
*/
public abstract T prepare(S s);
/**
* 执行数据转换操作---抽象
* @param <T>
* @param t
* @return
*/
public abstract void replenishOrder(T t);
/**
* 入库保存---抽象
* @param <T>
* @param saveInfo
* @return
*/
public abstract boolean doSaveInTransactional(T saveInfo);
/**
* 订单入库处理失败后操作---抽象
* @param originalOrder
* @return
*/
public abstract void executeError(S s, Exception e);
/**
* 保存前置处理方法---非抽象
* @param o
*/
public void doBeforeSaveDb(T o) {
}
/**
* 保存成功后置处理方法---非抽象
* @param o
*/
public void doAfterSaveDb(T o) {
}
/**
* 前置校验---非抽象
* @param t
* @return
*/
public boolean preCheck(T t) {
return Boolean.TRUE;
}
/**
* 删除临时数据---
抽象
* @param orderId
* @return
*/
public abstract boolean deleteOriginal(T t);
// 下面是各个类型的公共方法,抽出在最上层
/**
* 查询订单下的商品信息
* @param orderInfo
* @return
*/
protected final Map<String, ResProductVO> queryPurchaseProductInfo(List<String> goodIdList) {
// ......
}
/**
* 查询订单所属供应商信息
* @param venderId
* @return
*/
protected final ResSupplierInfoVO queryPurchaseVenderInfo(String venderId) {
// ......
}
protected final ResLocationVO queryPurchaseShopInfo(String shopId){
}
/**
* 查询订单门店信息(物流点)
* @param shopId
* @param fromShopId
* @return
*/
protected final ResLocationVO queryPurchaseShopInfo(String shopId, String fromShopId) {
// ......
}
}
第二层(验收单)
/**
* 验收单临时数据handler类
*
* @author zhangfuping
*/
@Slf4j
public abstract class AbstractReceiptOrderHandler<S, T extends ReceiptOrderContext> extends AbstractOrderHandler<S, T> {
//ReceiptOrderContext 注意这个对象是在第二层,也就是说第三层的对象都可用这个Context解决,属于上线文对象
public ReceiptOrderContext prepareContext(String purchaseId, String venderId, String shopId, String placeId, Integer logistics) {
//第二层公共方法,抽出在第二层
}
@Override
public void replenishOrder(ReceiptOrderContext receiptContext) {
// 实现第一层方法,该方法在订货单中是公共的抽在第二层
}
@Override
public boolean doSaveInTransactional(ReceiptOrderContext receiptContext) {
// 实现第一层方法,该方法在订货单中是公共的抽在第二层
}
//第二层,抽象方法,每个底层不一样,所以抽为第二层抽象方法
abstract public Tuple5<BigDecimal, BigDecimal, BigDecimal, BigDecimal, BigDecimal> getTotalAmtInfo(String sheetid);
//第二层公共方法
protected ResBaseDcAreaConfigVO getDcAreaConfig(String dcCode, String areaCode) {
}
//第二层公共方法
protected void insertSapTranslog(String transType, String sheetId) {
}
private void replenishItemProductInfo(List<Receiptitem> receiptItemList) {
}
}
第三层:具体某个“订货单”类型的实现
/**
* @author kzh
* @version 1.0
* @description: 云创数据
* @date 2023/2/13 16:23
*/
@Service
@Slf4j
public class ReceiptYcOrderHandler extends AbstractReceiptOrderHandler<OriginalYcReceiptContext, ReceiptOrderContext> {
//查询原始订单
@Override
public List<OriginalYcReceiptContext> queryOriginalOrderList() {
// 实现第一层方法,最终实现
}
@Override
public ReceiptOrderContext prepare(OriginalYcReceiptContext context) {
// 实现第一层方法,最终实现
}
@Override
public void executeError(OriginalYcReceiptContext originalOrder, Exception e) {
// 实现第一层方法,最终实现
}
@Override
public boolean deleteOriginal(ReceiptOrderContext receiptOrderContext) {
// 实现第一层方法,最终实现
}
@Override
public void doAfterSaveDb(ReceiptOrderContext context) {
// 实现第一层方法,最终实现
}
public Tuple5<BigDecimal, BigDecimal, BigDecimal, BigDecimal, BigDecimal> getTotalAmtInfo(String sheetId) {
// 实现第二层方法,最终实现
}
}