cl
2026-04-21 228b881e5a893ec010a194ac42011a4169d0c590
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package com.vincent.rsf.server.manager.service;
 
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.server.common.datasource.DataSourceNames;
import com.vincent.rsf.server.common.datasource.UseDataSource;
import com.vincent.rsf.server.manager.entity.CusBarcodeSyncView;
import com.vincent.rsf.server.manager.mapper.CusBarcodeSyncViewMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
 
import javax.sql.DataSource;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
 
/**
 * cus_barcode_sync_view:barcode 即为物料号(含 # 等字符亦原样),对应 man_matnr.code。与 {@link CusItemSyncViewQueryService} 独立。
 * 查询不启事务;{@code NOT_SUPPORTED} 挂起外层事务,避免主库连接占用导致副库路由失效。
 */
@UseDataSource(DataSourceNames.DJ_CLOUD_WMS)
@Service
@Slf4j
public class CusBarcodeSyncViewQueryService {
 
    @Autowired
    private CusBarcodeSyncViewMapper cusBarcodeSyncViewMapper;
 
    @Autowired
    @Qualifier("cusItemSyncDataSource")
    private ObjectProvider<DataSource> cusItemSyncDataSourceProvider;
 
    public String effectiveDataSourceLabel() {
        return cusItemSyncDataSourceProvider.getIfAvailable() != null ? DataSourceNames.DJ_CLOUD_WMS : "none";
    }
 
    /** 视图 barcode 字段 trim 后即物料编码 */
    public static String matnrCodeFromBarcode(String barcode) {
        return StringUtils.trimToNull(barcode);
    }
 
    /** 单据物料号与视图 barcode 等值(均为整段物料号) */
    public static boolean rowMatchesOrderMatnr(String orderMatnr, String viewBarcode) {
        String o = StringUtils.trimToNull(orderMatnr);
        String b = matnrCodeFromBarcode(viewBarcode);
        return o != null && o.equals(b);
    }
 
    public static boolean orderMatnrHitsBarcodeView(String orderMatnr, Collection<Map<String, Object>> viewItems) {
        if (viewItems == null || viewItems.isEmpty()) {
            return false;
        }
        String oc = StringUtils.trimToNull(orderMatnr);
        if (oc == null) {
            return false;
        }
        return viewItems.stream().anyMatch(r -> rowMatchesOrderMatnr(oc, Objects.toString(r.get("barcode"), null)));
    }
 
    /** 挂起外层事务,查询本身不包事务 */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<Map<String, Object>> probeSample(int limit) {
        if (cusItemSyncDataSourceProvider.getIfAvailable() == null) {
            return Collections.emptyList();
        }
        int n = Math.min(50, Math.max(1, limit));
        IPage<CusBarcodeSyncView> page = cusBarcodeSyncViewMapper.selectPage(
                new Page<>(1, n),
                Wrappers.<CusBarcodeSyncView>lambdaQuery()
                        .select(
                                CusBarcodeSyncView::getBarcode,
                                CusBarcodeSyncView::getItemName,
                                CusBarcodeSyncView::getItemSpec,
                                CusBarcodeSyncView::getUnitNo));
        return toViewMaps(page.getRecords());
    }
 
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<Map<String, Object>> listByItemNos(Collection<String> itemNos) {
        if (itemNos == null || itemNos.isEmpty()) {
            return Collections.emptyList();
        }
        List<String> codes = itemNos.stream()
                .map(StringUtils::trimToNull)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (codes.isEmpty()) {
            return Collections.emptyList();
        }
        if (cusItemSyncDataSourceProvider.getIfAvailable() == null) {
            log.warn("dj-cloud-wms 数据源未配置,跳过 cus_barcode_sync_view");
            return Collections.emptyList();
        }
        List<CusBarcodeSyncView> rows = cusBarcodeSyncViewMapper.selectList(
                Wrappers.<CusBarcodeSyncView>lambdaQuery()
                        .in(CusBarcodeSyncView::getBarcode, codes)
                        .select(
                                CusBarcodeSyncView::getBarcode,
                                CusBarcodeSyncView::getItemName,
                                CusBarcodeSyncView::getItemSpec,
                                CusBarcodeSyncView::getUnitNo));
        return toViewMaps(rows);
    }
 
    private List<Map<String, Object>> toViewMaps(List<CusBarcodeSyncView> rows) {
        if (rows == null || rows.isEmpty()) {
            return Collections.emptyList();
        }
        return rows.stream().map(this::toViewRowMap).collect(Collectors.toList());
    }
 
    private Map<String, Object> toViewRowMap(CusBarcodeSyncView row) {
        Map<String, Object> m = new LinkedHashMap<>(4);
        m.put("barcode", row.getBarcode());
        m.put("item_name", row.getItemName());
        m.put("item_spec", row.getItemSpec());
        m.put("unit_no", row.getUnitNo());
        return m;
    }
}