设计模式-责任链模式案例

 一,用作车辆属性检查,车架号检查、车辆id检车、sku检查、场站检查、车辆sku检查

1.入口为定时任务触发,es车辆属性检查

package com.dst.common.job;

import com.dst.common.entitys.es.EsVehicleInfo;
import com.dst.common.util.checkEsData.AttributesCheckHandler;
import com.dst.common.util.checkEsData.CarIdCheckHandler;
import com.dst.common.util.checkEsData.CheckHandler;
import com.dst.common.util.checkEsData.SpuCodeCheckHandler;
import com.dst.common.util.checkEsData.StandardSkuCodeCheckHandler;
import com.dst.common.util.checkEsData.StationIdCheckHandler;
import com.dst.common.util.checkEsData.VinCodeCheckHandler;
import com.dst.modules.business.carinventory.service.IEsQueryService;
import com.dst.modules.business.vehicle.service.OperatingAttrManageService;
import com.dst.modules.business.vehicle.service.OperatingNewCarService;
import com.dst.modules.extend.GoodsAttributeServiceImpl;
import com.dstcar.common.utils.string.StringUtil;
import com.dstcar.entitys.goods.attributegroup.AttributeGroupAttrOut;
import com.dstcar.entitys.operating.newcar.OperatingNewCarBaseDTO;
import com.dstcar.entitys.operating.newcar.OperatingNewCarBaseWithAttrDTO;
import com.dstcar.entitys.operating.newcar.OperatingNewCarViewListQuery;
import com.dstcar.entitys.operating.vehicleattr.attr.VehicleAttrManageDTO;
import com.dstcar.entitys.operating.vehicleattr.attr.VehicleAttrManageQuery;
import com.github.pagehelper.PageInfo;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import static java.util.stream.Collectors.toList;

/**
 * 定时任务检查数据库中的数据和es中的数据不一致
 *
 * @author liu wei ping
 * @version 1.0
 * @date 2022-06-30 11:27:29
 */
@JobHandler("carInfoMatchEsJob")
@Component
@Slf4j
public class CarInfoMatchEsJob extends IJobHandler {

    @Autowired
    private OperatingNewCarService operatingNewCarService;

    @Autowired
    private IEsQueryService esQueryService;

    @Autowired
    private GoodsAttributeServiceImpl goodsAttributeService;
    @Autowired
    private OperatingAttrManageService operatingAttrManageService;


    @Override
    public ReturnT<String> execute(String param) throws Exception {
        try {
            List<AttributeGroupAttrOut> configSkuAttrList = goodsAttributeService.getGroupAttrListByKey();
            List<String> configSkuAttrIdList =
                    configSkuAttrList.stream().map(AttributeGroupAttrOut::getAttrId).collect(toList());

            OperatingNewCarViewListQuery query = new OperatingNewCarViewListQuery();
            query.setPageSize(200);
            query.setPageNum(1);
            // 查在库库存
            query.setStationId(-1);
            PageInfo<OperatingNewCarBaseDTO> basicCarPageInfo =
                    operatingNewCarService.getOperatingNewCarBaseListPage(query);

            Set<String> vinCodes =
                    basicCarPageInfo.getList().stream().map(OperatingNewCarBaseDTO::getVinCode).collect(Collectors.toSet());

            // 只查车与sku定义相关的一些属性
            Map<String, List<VehicleAttrManageDTO>> vinAttrMap = getVinCodeAttrListMap(configSkuAttrIdList, vinCodes);
            List<EsVehicleInfo> esInfos = esQueryService.getEsVehicleInfoByVinCodes(new ArrayList<>(vinCodes), 0, 200);
            List<OperatingNewCarBaseWithAttrDTO> attrDTOList = getOperatingNewCarBaseWithAttrs(basicCarPageInfo,
                    vinAttrMap);

            // 比较结果(以数据库为准) ,比较carId,carNo,standardSkuCode,spuCode,stationId,attributes
            checkInfoWithEs(attrDTOList, esInfos);

            for (int j = 2; j <= basicCarPageInfo.getPages(); j++) {
                query.setPageNum(j);
                basicCarPageInfo = operatingNewCarService.getOperatingNewCarBaseListPage(query);
                vinCodes =
                        basicCarPageInfo.getList().stream().map(OperatingNewCarBaseDTO::getVinCode).collect(Collectors.toSet());
                esInfos = esQueryService.getEsVehicleInfoByVinCodes(new ArrayList<>(vinCodes),0,200);
                vinAttrMap = getVinCodeAttrListMap(configSkuAttrIdList, vinCodes);
                attrDTOList = getOperatingNewCarBaseWithAttrs(basicCarPageInfo, vinAttrMap);
                // 校验数据
                checkInfoWithEs(attrDTOList, esInfos);
                log.info("车辆SKU数据库数据与ES数据校验第 {} 页完成...", j);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return ReturnT.SUCCESS;
        } catch (Exception e) {
            XxlJobLogger.log("定时任务检查数据库中的数据和es中的数据不一致报错: " + e.getMessage());
        }
        return ReturnT.FAIL;

    }

    private List<OperatingNewCarBaseWithAttrDTO> getOperatingNewCarBaseWithAttrs(PageInfo<OperatingNewCarBaseDTO> basicCarPageInfo, Map<String, List<VehicleAttrManageDTO>> vinAttrMap) {
        List<OperatingNewCarBaseWithAttrDTO> attrDTOList =
                basicCarPageInfo.getList().stream().map(OperatingNewCarBaseDTO::toChild).collect(toList());
        attrDTOList.forEach(vo -> vo.setAttrs(vinAttrMap.get(vo.getVinCode())));
        return attrDTOList;
    }

    private Map<String, List<VehicleAttrManageDTO>> getVinCodeAttrListMap(List<String> configSkuAttrIdList,
                                                                          Set<String> vinCodes) {
        List<VehicleAttrManageDTO> skuAttrs =
                operatingAttrManageService.find(VehicleAttrManageQuery.builder()
                        .attrIds(configSkuAttrIdList)
                        .vinCodes(new ArrayList<>(vinCodes))
                        .build());
        return skuAttrs.stream().collect(Collectors.groupingBy(VehicleAttrManageDTO::getVinCode));
    }

    private void checkInfoWithEs(List<OperatingNewCarBaseWithAttrDTO> cars, List<EsVehicleInfo> esInfos) {
        if (CollectionUtils.isEmpty(cars)) {
            return;
        }
        CheckHandler.Builder<OperatingNewCarBaseWithAttrDTO> builder = new CheckHandler.Builder<>();
        builder.addHandler(new VinCodeCheckHandler())
                .addHandler(new CarIdCheckHandler())
                .addHandler(new StandardSkuCodeCheckHandler())
                .addHandler(new SpuCodeCheckHandler())
                .addHandler(new StationIdCheckHandler())
                .addHandler(new AttributesCheckHandler());
        StringBuilder stringBuilder;
        for (OperatingNewCarBaseWithAttrDTO baseDTO : cars) {
            stringBuilder = new StringBuilder();
            builder.build().doCheck(baseDTO, esInfos, stringBuilder);
            if(!StringUtil.isEmpty(stringBuilder.toString())){
                stringBuilder.insert(0,"vinCode["+baseDTO.getVinCode()+"]");
                log.error(stringBuilder.toString());
            }
        }
    }
}
package com.dst.common.util.checkEsData;

import com.dst.common.entitys.es.EsVehicleInfo;
import java.util.List;

/**
 * @author liu wei ping
 * @version 1.0
 * @date 2022-06-30 18:10:06
 */
public abstract class CheckHandler<T> {
    protected CheckHandler<T> next;

    private void next(CheckHandler<T> next) {
        this.next = next;
    }

    /**
     * 校验
     *
     * @param baseDTO       实体
     * @param esInfos       es中的数据
     * @param stringBuilder stringBuilder
     */
    public abstract void doCheck(T baseDTO, List<? extends EsVehicleInfo> esInfos,
                                 StringBuilder stringBuilder);

    public static class Builder<T> {
        private CheckHandler<T> head;
        private CheckHandler<T> tail;

        public Builder<T> addHandler(CheckHandler<T> handler) {
            if (this.head == null) {
                this.head = this.tail = handler;
                return this;
            }

            this.tail.next(handler);
            this.tail = handler;
            return this;
        }

        public CheckHandler<T> build() {
            return this.head;
        }
    }

}
package com.dst.common.util.checkEsData;

import com.dst.common.entitys.es.EsVehicleInfo;
import com.dstcar.entitys.operating.newcar.OperatingNewCarBaseWithAttrDTO;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * 车架号校验
 *
 * @author liu wei ping
 * @version 1.0
 * @date 2022-06-30 18:30:45
 */
public class VinCodeCheckHandler extends CheckHandler<OperatingNewCarBaseWithAttrDTO> {

    @Override
    public void doCheck(OperatingNewCarBaseWithAttrDTO baseDTO, List<? extends EsVehicleInfo> esInfos,
                        StringBuilder stringBuilder) {
        List<String> vinCodes = esInfos.stream().map(EsVehicleInfo::getVinCode).collect(toList());
        if (!vinCodes.contains(baseDTO.getVinCode())) {
            // 车架号不存在不往下校验了
            stringBuilder.append("vinCode ").append("does not exit in es");
        }

    }


}
package com.dst.common.util.checkEsData;

import com.dst.common.entitys.es.EsVehicleInfo;
import com.dstcar.entitys.operating.newcar.OperatingNewCarBaseWithAttrDTO;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author liu wei ping
 * @version 1.0
 * @date 2022-06-30 18:41:49
 */
public class CarIdCheckHandler extends CheckHandler<OperatingNewCarBaseWithAttrDTO> {
    @Override
    public void doCheck(OperatingNewCarBaseWithAttrDTO baseDTO, List<? extends EsVehicleInfo> esInfos,
                        StringBuilder stringBuilder) {
        Optional<? extends EsVehicleInfo> info =
                esInfos.stream().filter(esInfo -> esInfo.getVinCode().equals(baseDTO.getVinCode())).findFirst();
        if (info.isPresent() && !info.get().getCarId().equals(baseDTO.getCarId())) {
            stringBuilder.append("carId is different in es,in fact it is :").append(baseDTO.getCarId()).append("but " +
                    "in es it is :").append(info.get().getCarId());
        }

        if (Objects.nonNull(next)) {
            next.doCheck(baseDTO, esInfos, stringBuilder);
        }

    }
}
package com.dst.common.util.checkEsData;

import com.dst.common.entitys.es.EsVehicleInfo;
import com.dstcar.entitys.operating.newcar.OperatingNewCarBaseWithAttrDTO;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 标准sku编码校验
 *
 * @author liu wei ping
 * @version 1.0
 * @date 2022-07-01 10:26:39
 */
public class StandardSkuCodeCheckHandler extends CheckHandler<OperatingNewCarBaseWithAttrDTO> {
    @Override
    public void doCheck(OperatingNewCarBaseWithAttrDTO baseDTO, List<? extends EsVehicleInfo> esInfos,
                        StringBuilder stringBuilder) {
        Optional<? extends EsVehicleInfo> info =
                esInfos.stream().filter(esInfo -> esInfo.getVinCode().equals(baseDTO.getVinCode())).findFirst();
        if (info.isPresent() && !info.get().getStandardSkuCode().equals(baseDTO.getStandardSkuCode())) {
            stringBuilder.append("standardSkuCode is different in es,in fact it is :").append(baseDTO.getStandardSkuCode()).append(
                    "but " +
                            "in es it is :").append(info.get().getStandardSkuCode());
        }

        if (Objects.nonNull(next)) {
            next.doCheck(baseDTO, esInfos, stringBuilder);
        }

    }
}
package com.dst.common.util.checkEsData;

import com.dst.common.entitys.es.EsVehicleInfo;
import com.dstcar.entitys.operating.newcar.OperatingNewCarBaseWithAttrDTO;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * spuCode校验
 *
 * @author liu wei ping
 * @version 1.0
 * @date 2022-07-01 10:28:17
 */
public class SpuCodeCheckHandler extends CheckHandler<OperatingNewCarBaseWithAttrDTO> {
    @Override
    public void doCheck(OperatingNewCarBaseWithAttrDTO baseDTO, List<? extends EsVehicleInfo> esInfos,
                        StringBuilder stringBuilder) {
        Optional<? extends EsVehicleInfo> info =
                esInfos.stream().filter(esInfo -> esInfo.getVinCode().equals(baseDTO.getVinCode())).findFirst();
        if (info.isPresent() && !info.get().getSpuCode().equals(baseDTO.getSpuCode())) {
            stringBuilder.append("spuCode is different in es,in fact it is :").append(baseDTO.getSkuCode()).append(
                    "but " +
                            "in es it is :").append(info.get().getSpuCode());
        }

        if (Objects.nonNull(next)) {
            next.doCheck(baseDTO, esInfos, stringBuilder);
        }
    }
}
package com.dst.common.util.checkEsData;

import com.dst.common.entitys.es.EsVehicleInfo;
import com.dstcar.entitys.operating.newcar.OperatingNewCarBaseWithAttrDTO;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 场站id 校验
 *
 * @author liu wei ping
 * @version 1.0
 * @date 2022-07-01 10:30:22
 */
public class StationIdCheckHandler extends CheckHandler<OperatingNewCarBaseWithAttrDTO> {
    @Override
    public void doCheck(OperatingNewCarBaseWithAttrDTO baseDTO, List<? extends EsVehicleInfo> esInfos,
                        StringBuilder stringBuilder) {
        Optional<? extends EsVehicleInfo> info =
                esInfos.stream().filter(esInfo -> esInfo.getVinCode().equals(baseDTO.getVinCode())).findFirst();
        if (info.isPresent() && !info.get().getStationId().equals(baseDTO.getStationId())) {
            stringBuilder.append("stationId is different in es,in fact it is :").append(baseDTO.getStationId()).append(
                    "but " +
                            "in es it is :").append(info.get().getStationId());
        }

        if (Objects.nonNull(next)) {
            next.doCheck(baseDTO, esInfos, stringBuilder);
        }
    }
}
package com.dst.common.util.checkEsData;

import com.dst.common.entitys.es.EsVehicleInfo;
import com.dstcar.common.utils.string.StringUtil;
import com.dstcar.entitys.operating.newcar.OperatingNewCarBaseWithAttrDTO;
import com.dstcar.entitys.operating.vehicleattr.attr.VehicleAttrManageDTO;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 属性比较
 *
 * @author liu wei ping
 * @version 1.0
 * @date 2022-07-01 10:32:41
 */
public class AttributesCheckHandler extends CheckHandler<OperatingNewCarBaseWithAttrDTO> {
    @Override
    public void doCheck(OperatingNewCarBaseWithAttrDTO baseDTO, List<? extends EsVehicleInfo> esInfos,
                        StringBuilder stringBuilder) {

        Optional<? extends EsVehicleInfo> info =
                esInfos.stream().filter(esInfo -> esInfo.getVinCode().equals(baseDTO.getVinCode())).findFirst();

        List<VehicleAttrManageDTO> attrs = baseDTO.getAttrs();
        Map<String, VehicleAttrManageDTO> attrMap = attrs.stream()
                .collect(Collectors.toMap(VehicleAttrManageDTO::getAttrId, Function.identity()));

        if (info.isPresent()) {
            // ES 中的属性map 的格式为 attrId:attrValueId/attrValueName(针对手动输入的属性)
            Map<String, Object> infoAttrMap = info.get().getAttributes();
            for (Map.Entry<String, VehicleAttrManageDTO> entry : attrMap.entrySet()) {
                //  分情况, 当attrValueId 不为空则比较attrValueId 否则就比较attrValueName
                if (!StringUtil.isEmpty(entry.getValue()) && !infoAttrMap.get(entry.getKey()).equals(entry.getValue())) {
                    stringBuilder.append("attribute is different in es,attrId is")
                            .append(entry.getKey())
                            .append("  attrName is ")
                            .append(entry.getValue().getAttrName())
                            .append("value in es is")
                            .append(infoAttrMap.get(entry.getKey()))
                            .append("value in db is ")
                            .append(entry.getValue().getAttrValueId());
                }

                if (StringUtil.isEmpty(entry.getValue()) && !infoAttrMap.get(entry.getKey()).equals(entry.getValue())) {
                    stringBuilder.append("attribute is different in es,attrId is")
                            .append(entry.getKey())
                            .append("  attrName is ")
                            .append(entry.getValue().getAttrName())
                            .append("value in es is")
                            .append(infoAttrMap.get(entry.getKey()))
                            .append("value in db is ")
                            .append(entry.getValue().getAttrValueName());
                }

            }

        }
        if (Objects.nonNull(next)) {
            next.doCheck(baseDTO, esInfos, stringBuilder);
        }
    }
}

2.使用责任链模式,加入链表结构,让检查方法顺序检查。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值