刘光辉
6 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package jnpf.elnService.formula.impl;
 
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.elnEntity.formula.ElnFormulaVersionEntity;
import jnpf.elnEntity.formula.ElnTemplateFormulaBindingEntity;
import jnpf.elnEntity.template.ElnTemplateVersionEntity;
import jnpf.elnMapper.ElnTemplateMapper;
import jnpf.elnMapper.ElnFormulaVersionMapper;
import jnpf.elnMapper.ElnTemplateFormulaBindingMapper;
import jnpf.elnService.template.ElnTemplateVersionCopyParticipant;
import jnpf.exception.DataException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
 
@Service
public class FormulaTemplateVersionCopyParticipant implements ElnTemplateVersionCopyParticipant {
    private final Store store;
    private final Supplier<String> idSupplier;
 
    @Autowired
    public FormulaTemplateVersionCopyParticipant(ElnTemplateMapper templateMapper,
            ElnTemplateFormulaBindingMapper bindingMapper,
            ElnFormulaVersionMapper formulaVersionMapper) {
        this(new MyBatisStore(templateMapper, bindingMapper, formulaVersionMapper),
                IdUtil::getSnowflakeNextIdStr);
    }
 
    public FormulaTemplateVersionCopyParticipant(Store store, Supplier<String> idSupplier) {
        this.store = store; this.idSupplier = idSupplier;
    }
 
    @Override
    public void afterBindingsActivated(String tenantId, String sourceTemplateId,
            String targetTemplateId, Map<String, String> bindingIdMap) {
        ElnTemplateVersionEntity target = store.findTemplate(tenantId, targetTemplateId);
        if (target == null || !StringUtils.hasText(target.getShengbanCaozuoBianma()))
            throw new DataException("目标模板升版操作不存在");
        for (ElnTemplateFormulaBindingEntity source
                : store.listActive(tenantId, sourceTemplateId)) {
            ElnFormulaVersionEntity formulaVersion = store.findFormulaVersion(
                    tenantId, source.getGongshiBanbenId());
            boolean published = formulaVersion != null
                    && "PUBLISHED".equals(formulaVersion.getBizStatus());
            boolean draftTargetPreRelease = formulaVersion != null
                    && "DRAFT".equals(target.getBizStatus())
                    && "PRE_RELEASE".equals(formulaVersion.getBizStatus());
            if ((!published && !draftTargetPreRelease)
                    || !source.getGongshiDingyiId().equals(formulaVersion.getGongshiDingyiId()))
                throw new DataException("模板升版只能继承已发布公式版本或由草稿模板继承预发布公式版本");
            String operation = target.getShengbanCaozuoBianma() + ":" + source.getId();
            ElnTemplateFormulaBindingEntity existing = store.findByOperation(
                    tenantId, targetTemplateId, operation);
            Map<String, String> parameters = new LinkedHashMap<>();
            for (Map.Entry<String, String> item : source.getCanshuYingshe().entrySet()) {
                String mapped = bindingIdMap.get(item.getValue());
                if (!StringUtils.hasText(mapped)) throw new DataException("模板升版字段映射不完整");
                parameters.put(item.getKey(), mapped);
            }
            String resultBinding = bindingIdMap.get(source.getJieguoBangdingId());
            if (!StringUtils.hasText(resultBinding)) throw new DataException("模板升版结果字段映射缺失");
            ElnTemplateFormulaBindingEntity copied = new ElnTemplateFormulaBindingEntity();
            copied.setId(idSupplier.get()); copied.setFTenantId(tenantId);
            copied.setMubanId(targetTemplateId);
            copied.setGongshiDingyiId(source.getGongshiDingyiId());
            copied.setGongshiBanbenId(source.getGongshiBanbenId());
            copied.setCanshuYingshe(parameters); copied.setJieguoBangdingId(resultBinding);
            copied.setBangdingZhuangtai("PENDING"); copied.setCaozuoBianma(operation);
            copied.setLaiyuanGongshiBangdingId(source.getId()); copied.setDaoqiShijian(null);
            copied.setFVersion(1); copied.setFCreatorTime(new Date()); copied.setFDeleteMark(0);
            if (existing != null) {
                if (!sameCopy(existing, copied))
                    throw new DataException("操作码已用于其他公式映射请求");
                continue;
            }
            if (!store.insertIfAbsent(copied)) {
                ElnTemplateFormulaBindingEntity concurrent = store.findByOperation(
                        tenantId, targetTemplateId, operation);
                if (concurrent == null || !sameCopy(concurrent, copied))
                    throw new DataException("操作码已用于其他公式映射请求");
            }
        }
    }
 
    private static boolean sameCopy(ElnTemplateFormulaBindingEntity actual,
            ElnTemplateFormulaBindingEntity planned) {
        return Objects.equals(actual.getFTenantId(), planned.getFTenantId())
                && Objects.equals(actual.getMubanId(), planned.getMubanId())
                && Objects.equals(actual.getLaiyuanGongshiBangdingId(),
                    planned.getLaiyuanGongshiBangdingId())
                && Objects.equals(actual.getGongshiDingyiId(), planned.getGongshiDingyiId())
                && Objects.equals(actual.getGongshiBanbenId(), planned.getGongshiBanbenId())
                && Objects.equals(actual.getCanshuYingshe(), planned.getCanshuYingshe())
                && Objects.equals(actual.getJieguoBangdingId(), planned.getJieguoBangdingId())
                && Objects.equals(actual.getCaozuoBianma(), planned.getCaozuoBianma())
                && actual.getDaoqiShijian() == null
                && ("PENDING".equals(actual.getBangdingZhuangtai())
                    || "ACTIVE".equals(actual.getBangdingZhuangtai()));
    }
 
    public interface Store {
        ElnTemplateVersionEntity findTemplate(String tenantId, String templateId);
        List<ElnTemplateFormulaBindingEntity> listActive(String tenantId, String sourceTemplateId);
        ElnFormulaVersionEntity findFormulaVersion(String tenantId, String versionId);
        ElnTemplateFormulaBindingEntity findByOperation(
                String tenantId, String targetTemplateId, String operationCode);
        boolean insertIfAbsent(ElnTemplateFormulaBindingEntity binding);
    }
 
    private static final class MyBatisStore implements Store {
        private final ElnTemplateMapper templates;
        private final ElnTemplateFormulaBindingMapper bindings;
        private final ElnFormulaVersionMapper formulaVersions;
        private MyBatisStore(ElnTemplateMapper templates,
                ElnTemplateFormulaBindingMapper bindings,
                ElnFormulaVersionMapper formulaVersions) {
            this.templates = templates; this.bindings = bindings;
            this.formulaVersions = formulaVersions;
        }
        @Override public ElnTemplateVersionEntity findTemplate(String tenantId, String templateId) {
            return templates.selectOne(Wrappers.<ElnTemplateVersionEntity>lambdaQuery()
                    .eq(ElnTemplateVersionEntity::getFTenantId, tenantId)
                    .eq(ElnTemplateVersionEntity::getId, templateId)
                    .and(q -> q.isNull(ElnTemplateVersionEntity::getFDeleteMark)
                            .or().eq(ElnTemplateVersionEntity::getFDeleteMark, 0)));
        }
        @Override public List<ElnTemplateFormulaBindingEntity> listActive(
                String tenantId, String sourceTemplateId) {
            return bindings.selectList(Wrappers.<ElnTemplateFormulaBindingEntity>lambdaQuery()
                    .eq(ElnTemplateFormulaBindingEntity::getFTenantId, tenantId)
                    .eq(ElnTemplateFormulaBindingEntity::getMubanId, sourceTemplateId)
                    .eq(ElnTemplateFormulaBindingEntity::getBangdingZhuangtai, "ACTIVE")
                    .and(q -> q.isNull(ElnTemplateFormulaBindingEntity::getFDeleteMark)
                            .or().eq(ElnTemplateFormulaBindingEntity::getFDeleteMark, 0))
                    .orderByAsc(ElnTemplateFormulaBindingEntity::getId));
        }
        @Override public ElnFormulaVersionEntity findFormulaVersion(
                String tenantId, String versionId) {
            return formulaVersions.selectOne(Wrappers.<ElnFormulaVersionEntity>lambdaQuery()
                    .eq(ElnFormulaVersionEntity::getFTenantId, tenantId)
                    .eq(ElnFormulaVersionEntity::getId, versionId)
                    .and(q -> q.isNull(ElnFormulaVersionEntity::getFDeleteMark)
                            .or().eq(ElnFormulaVersionEntity::getFDeleteMark, 0)));
        }
        @Override public ElnTemplateFormulaBindingEntity findByOperation(
                String tenantId, String targetTemplateId, String operationCode) {
            return bindings.selectOne(Wrappers.<ElnTemplateFormulaBindingEntity>lambdaQuery()
                    .eq(ElnTemplateFormulaBindingEntity::getFTenantId, tenantId)
                    .eq(ElnTemplateFormulaBindingEntity::getMubanId, targetTemplateId)
                    .eq(ElnTemplateFormulaBindingEntity::getCaozuoBianma, operationCode)
                    .and(q -> q.isNull(ElnTemplateFormulaBindingEntity::getFDeleteMark)
                            .or().eq(ElnTemplateFormulaBindingEntity::getFDeleteMark, 0)));
        }
        @Override public boolean insertIfAbsent(ElnTemplateFormulaBindingEntity binding) {
            return bindings.insertIfAbsent(binding) == 1;
        }
    }
}