yeg
2026-09-29 b78295e8da96c3e5e76befeef9582ce5273dbb74
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package com.battery.business.service.impl;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.battery.business.domain.TBatteryGroupField;
import com.battery.business.domain.TBatteryGroupTemplate;
import com.battery.business.domain.TBatteryGroupTemplateField;
import com.battery.business.mapper.TBatteryGroupTemplateMapper;
import com.battery.business.service.ITBatteryGroupTemplateService;
 
/**
 * 电池组模板 Service 实现。
 *
 * @author ruoyi
 */
@Service
public class TBatteryGroupTemplateServiceImpl implements ITBatteryGroupTemplateService
{
    private static final String NORMAL = "0";
 
    @Autowired
    private TBatteryGroupTemplateMapper batteryGroupTemplateMapper;
 
    /**
     * 按主键读取电池组模板,并装配模板的字段关系与显示顺序。
     *
     * @param templateId 模板主键
     * @return 模板及其字段关系
     * @throws ServiceException 模板ID为空或模板不存在
     */
    @Override
    public TBatteryGroupTemplate selectBatteryGroupTemplateById(Long templateId)
    {
        if (templateId == null)
        {
            throw new ServiceException("模板ID不能为空");
        }
        TBatteryGroupTemplate template = batteryGroupTemplateMapper.selectBatteryGroupTemplateById(templateId);
        if (template == null)
        {
            throw new ServiceException("电池组模板不存在");
        }
        template.setFields(batteryGroupTemplateMapper.selectTemplateFields(templateId));
        return template;
    }
 
    /**
     * 返回正常状态的模板选项,供电池组选择字段模板。
     *
     * @return 模板选项列表;没有可用模板时为空列表
     */
    @Override
    public List<TBatteryGroupTemplate> selectBatteryGroupTemplateOptions()
    {
        return batteryGroupTemplateMapper.selectBatteryGroupTemplateOptions();
    }
 
    /**
     * 新增电池组模板,在同一事务内写入模板主记录与字段关系。
     *
     * <p>前置条件:模板名称在当前数据中唯一,字段不能为空且不能重复,字段须启用,
     * 排序数量与字段数量一致。字段关系整体按提交的字段与顺序写入。</p>
     *
     * @param template 模板配置,含字段主键与可选的显示顺序
     * @return 写入的模板主记录行数
     * @throws ServiceException 模板信息为空、名称重复、字段为空或重复、字段不存在或已禁用、排序不合法
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertBatteryGroupTemplate(TBatteryGroupTemplate template)
    {
        validateTemplate(template, false);
        template.setTemplateName(trimToNull(template.getTemplateName()));
        if (StringUtils.isEmpty(template.getUpdateBy()))
        {
            template.setUpdateBy(template.getCreateBy());
        }
        template.setCreateTime(new Date());
        // STEP 1: 写入模板主记录,字段关系依赖本次生成的主键。
        int rows = batteryGroupTemplateMapper.insertBatteryGroupTemplate(template);
        // STEP 2: 在同一事务内整体写入字段关系与显示顺序。
        replaceFields(template);
        return rows;
    }
 
    /**
     * 修改电池组模板,字段关系按提交内容整体替换。
     *
     * <p>前置条件:模板存在,模板名称不与其它模板重复(允许与自身同名),
     * 字段与排序的校验要求同新增。已有电池组引用的只是字段定义,模板变更不改写电池组当前字段值。</p>
     *
     * @param template 模板配置,须带模板主键
     * @return 更新的模板主记录行数
     * @throws ServiceException 模板ID为空、模板不存在、名称重复或字段与排序校验不通过
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateBatteryGroupTemplate(TBatteryGroupTemplate template)
    {
        if (template == null || template.getTemplateId() == null)
        {
            throw new ServiceException("模板ID不能为空");
        }
        if (batteryGroupTemplateMapper.selectBatteryGroupTemplateById(template.getTemplateId()) == null)
        {
            throw new ServiceException("电池组模板不存在");
        }
        validateTemplate(template, true);
        template.setTemplateName(trimToNull(template.getTemplateName()));
        template.setUpdateTime(new Date());
        // STEP 1: 更新模板主记录。
        int rows = batteryGroupTemplateMapper.updateBatteryGroupTemplate(template);
        // STEP 2: 字段关系整体替换:先清理旧关系再按提交顺序写入。
        replaceFields(template);
        return rows;
    }
 
    private void validateTemplate(TBatteryGroupTemplate template, boolean update)
    {
        if (template == null)
        {
            throw new ServiceException("电池组模板信息不能为空");
        }
        if (update && template.getTemplateId() == null)
        {
            throw new ServiceException("模板ID不能为空");
        }
        template.setTemplateName(trimToNull(template.getTemplateName()));
        if (StringUtils.isEmpty(template.getTemplateName()))
        {
            throw new ServiceException("模板名称不能为空");
        }
        TBatteryGroupTemplate existing = batteryGroupTemplateMapper
                .selectBatteryGroupTemplateByName(template.getTemplateName());
        if (existing != null && (template.getTemplateId() == null
                || !template.getTemplateId().equals(existing.getTemplateId())))
        {
            throw new ServiceException("模板名称已存在");
        }
        List<Long> fieldIds = template.getFieldIds();
        if (fieldIds == null || fieldIds.isEmpty())
        {
            throw new ServiceException("模板字段不能为空");
        }
        Set<Long> uniqueIds = new HashSet<>();
        for (Long fieldId : fieldIds)
        {
            if (fieldId == null || !uniqueIds.add(fieldId))
            {
                throw new ServiceException("模板字段不能重复或为空");
            }
        }
        List<TBatteryGroupField> fields = batteryGroupTemplateMapper.selectEnabledFieldsByIds(fieldIds);
        if (fields == null || fields.size() != fieldIds.size())
        {
            throw new ServiceException("模板包含不存在或已禁用的电池组字段");
        }
        if (template.getSortOrders() != null && template.getSortOrders().size() != fieldIds.size())
        {
            throw new ServiceException("字段排序数量必须与字段数量一致");
        }
        if (template.getSortOrders() != null)
        {
            for (Integer sortOrder : template.getSortOrders())
            {
                if (sortOrder == null || sortOrder < 0)
                {
                    throw new ServiceException("字段排序必须为非负整数");
                }
            }
        }
    }
 
    private void replaceFields(TBatteryGroupTemplate template)
    {
        if (template.getTemplateId() == null)
        {
            throw new ServiceException("模板ID不能为空");
        }
        batteryGroupTemplateMapper.deleteTemplateFields(template.getTemplateId());
        List<TBatteryGroupTemplateField> relations = new ArrayList<>();
        List<Long> fieldIds = template.getFieldIds();
        List<Integer> sortOrders = template.getSortOrders();
        for (int i = 0; i < fieldIds.size(); i++)
        {
            TBatteryGroupTemplateField relation = new TBatteryGroupTemplateField();
            relation.setTemplateId(template.getTemplateId());
            relation.setFieldId(fieldIds.get(i));
            relation.setSortOrder(sortOrders == null ? i : sortOrders.get(i));
            relation.setCreateBy(StringUtils.isEmpty(template.getUpdateBy()) ? template.getCreateBy() : template.getUpdateBy());
            relation.setCreateTime(new Date());
            relation.setDelFlag(0L);
            relations.add(relation);
        }
        batteryGroupTemplateMapper.batchInsertTemplateFields(relations);
    }
 
    private String trimToNull(String value)
    {
        String trimmed = StringUtils.trim(value);
        return StringUtils.isEmpty(trimmed) ? null : trimmed;
    }
}