Merge remote-tracking branch 'origin/main'

main
liutao 2 days ago
commit 850cb88dfc

@ -102,7 +102,7 @@ public class ErpProductCategoryController {
@GetMapping("/simple-list") @GetMapping("/simple-list")
@Operation(summary = "获得产品分类精简列表", description = "只包含被开启的分类,主要用于前端的下拉选项") @Operation(summary = "获得产品分类精简列表", description = "只包含被开启的分类,主要用于前端的下拉选项")
public CommonResult<List<ErpProductCategoryRespVO>> getProductCategorySimpleList(@RequestParam("type") Integer type) { public CommonResult<List<ErpProductCategoryRespVO>> getProductCategorySimpleList(@RequestParam(value = "type",required = false) Integer type) {
List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList( List<ErpProductCategoryDO> list = productCategoryService.getProductCategoryList(
new ErpProductCategoryListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()).setType(type)); new ErpProductCategoryListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()).setType(type));
return success(convertList(list, category -> new ErpProductCategoryRespVO() return success(convertList(list, category -> new ErpProductCategoryRespVO()

@ -122,7 +122,7 @@ public class IotMqttRuntimeCache {
} }
List<CachedPointRule> parsedRules = new ArrayList<>(); List<CachedPointRule> parsedRules = new ArrayList<>();
for (DevicePointRulesDO rule : rules) { for (DevicePointRulesDO rule : rules) {
if (StringUtils.isBlank(rule.getFieldRule())) { if (StringUtils.isBlank(rule.getAlarmLevel()) || StringUtils.isBlank(rule.getFieldRule())) {
continue; continue;
} }
try { try {

@ -398,7 +398,6 @@ public class MqttDataHandler extends SuperConsumer<String> {
attributeCode, processedValue, attributeCode, processedValue,
JSON.toJSONString(pointRulesRespVO)); JSON.toJSONString(pointRulesRespVO));
handleMatchedSuccessRule(cachedRule.getRule(), pointRulesRespVO, processedValue, device, attributeCode, point); handleMatchedSuccessRule(cachedRule.getRule(), pointRulesRespVO, processedValue, device, attributeCode, point);
break;
} else { } else {
log.debug("规则不匹配: modelId={}, value={}, rule={}", log.debug("规则不匹配: modelId={}, value={}, rule={}",
attributeCode, processedValue, attributeCode, processedValue,

@ -12,24 +12,31 @@ import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceProductionDa
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceProductionDailyReportRespVO; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceProductionDailyReportRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicewarinningrecord.DeviceWarinningRecordDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
import cn.iocoder.yudao.module.mes.api.workteam.WorkTeamApi; import cn.iocoder.yudao.module.mes.api.workteam.WorkTeamApi;
import cn.iocoder.yudao.module.mes.api.workteam.dto.WorkTeamRespDTO; import cn.iocoder.yudao.module.mes.api.workteam.dto.WorkTeamRespDTO;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -57,8 +64,10 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
private static final String TEMPLATE_PATH = "excel/templates/fully-automatic-molding-production-daily-report-template.xlsx"; private static final String TEMPLATE_PATH = "excel/templates/fully-automatic-molding-production-daily-report-template.xlsx";
private static final String REPORT_PATH_PREFIX = "iot/device/production-daily-report"; private static final String REPORT_PATH_PREFIX = "iot/device/production-daily-report";
private static final String ALARM_LEVEL_DICT_TYPE = "alarm_registration";
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
@Resource @Resource
private DeviceMapper deviceMapper; private DeviceMapper deviceMapper;
@ -69,6 +78,8 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
@Resource @Resource
private WorkTeamApi workTeamApi; private WorkTeamApi workTeamApi;
@Resource @Resource
private DictDataApi dictDataApi;
@Resource
private FileService fileService; private FileService fileService;
@Resource @Resource
private FileMapper fileMapper; private FileMapper fileMapper;
@ -96,15 +107,19 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
if (!endTime.isAfter(startTime)) { if (!endTime.isAfter(startTime)) {
endTime = endTime.plusDays(1); endTime = endTime.plusDays(1);
} }
log.info("[production-daily-report] generate request: reportDate={}, workTeamId={}, workTeamName={}, startTime={}, endTime={}, deviceIds={}",
reqVO.getReportDate(), reqVO.getWorkTeamId(), workTeam.getTeamName(), startTime, endTime, deviceIds);
List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items = buildCapacityItems(deviceIds, deviceMap, startTime, endTime); List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items = buildCapacityItems(deviceIds, deviceMap, startTime, endTime);
byte[] excelContent = buildExcel(reqVO, workTeam, startTime, endTime, items); byte[] excelContent = buildExcel(reqVO, workTeam, startTime, endTime, items, deviceIds);
String fileName = String.format("全自动成型机生产日报表_%s_%s_%s.xlsx", String fileName = String.format("全自动成型机生产日报表_%s_%s_%s.xlsx",
reqVO.getReportDate().format(DateTimeFormatter.BASIC_ISO_DATE), reqVO.getWorkTeamId(), System.currentTimeMillis()); reqVO.getReportDate().format(DateTimeFormatter.BASIC_ISO_DATE), reqVO.getWorkTeamId(), System.currentTimeMillis());
String filePath = String.format("%s/date=%s/workTeamId=%s/deviceIds=%s/deviceTags=%s/%s", String filePath = String.format("%s/date=%s/workTeamId=%s/deviceIds=%s/deviceTags=%s/%s",
REPORT_PATH_PREFIX, reqVO.getReportDate(), reqVO.getWorkTeamId(), joinDeviceIds(deviceIds), buildDeviceTags(deviceIds), fileName); REPORT_PATH_PREFIX, reqVO.getReportDate(), reqVO.getWorkTeamId(), joinDeviceIds(deviceIds), buildDeviceTags(deviceIds), fileName);
Map<String, String> file = fileService.createFile(fileName, filePath, excelContent); Map<String, String> file = fileService.createFile(fileName, filePath, excelContent);
log.info("[production-daily-report] file created: fileName={}, filePath={}, fileUrl={}, contentLength={}",
file.get("fileName"), filePath, file.get("fileUrl"), excelContent.length);
DeviceProductionDailyReportRespVO respVO = buildBaseResp(reqVO.getReportDate(), workTeam, startTime, endTime, deviceIds); DeviceProductionDailyReportRespVO respVO = buildBaseResp(reqVO.getReportDate(), workTeam, startTime, endTime, deviceIds);
respVO.setFileName(file.get("fileName")); respVO.setFileName(file.get("fileName"));
@ -141,7 +156,7 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
Map<Long, DeviceDO> deviceMap, Map<Long, DeviceDO> deviceMap,
LocalDateTime startTime, LocalDateTime startTime,
LocalDateTime endTime) { LocalDateTime endTime) {
Map<Long, List<DeviceContactModelDO>> capacityPointMap = queryCapacityPoints(deviceIds); Map<Long, DeviceContactModelDO> capacityPointMap = queryCapacityPoints(deviceIds);
Map<Long, Map<String, Object>> firstRows = tDengineService.queryDevicesEarliestRow(deviceIds, Map<Long, Map<String, Object>> firstRows = tDengineService.queryDevicesEarliestRow(deviceIds,
startTime.format(DATE_TIME_FORMATTER), endTime.format(DATE_TIME_FORMATTER)); startTime.format(DATE_TIME_FORMATTER), endTime.format(DATE_TIME_FORMATTER));
Map<Long, Map<String, Object>> lastRows = tDengineService.queryDevicesLatestRow(deviceIds, Map<Long, Map<String, Object>> lastRows = tDengineService.queryDevicesLatestRow(deviceIds,
@ -150,31 +165,28 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items = new ArrayList<>(); List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items = new ArrayList<>();
for (Long deviceId : deviceIds) { for (Long deviceId : deviceIds) {
DeviceDO device = deviceMap.get(deviceId); DeviceDO device = deviceMap.get(deviceId);
List<DeviceContactModelDO> points = capacityPointMap.getOrDefault(deviceId, Collections.emptyList()); DeviceContactModelDO point = capacityPointMap.get(deviceId);
if (CollUtil.isEmpty(points)) { if (point == null) {
items.add(buildEmptyCapacityItem(device)); items.add(buildEmptyCapacityItem(device));
continue; continue;
} }
Map<String, Object> firstRow = firstRows.get(deviceId); Map<String, Object> firstRow = firstRows.get(deviceId);
Map<String, Object> lastRow = lastRows.get(deviceId); Map<String, Object> lastRow = lastRows.get(deviceId);
for (DeviceContactModelDO point : points) { items.add(buildCapacityItem(device, point, firstRow, lastRow));
items.add(buildCapacityItem(device, point, firstRow, lastRow));
}
} }
return items; return items;
} }
private Map<Long, List<DeviceContactModelDO>> queryCapacityPoints(List<Long> deviceIds) { private Map<Long, DeviceContactModelDO> queryCapacityPoints(List<Long> deviceIds) {
List<DeviceContactModelDO> points = deviceContactModelMapper.selectList( List<DeviceContactModelDO> points = deviceContactModelMapper.selectList(
Wrappers.<DeviceContactModelDO>lambdaQuery() Wrappers.<DeviceContactModelDO>lambdaQuery()
.in(DeviceContactModelDO::getDeviceId, deviceIds) .in(DeviceContactModelDO::getDeviceId, deviceIds)
.and(wrapper -> wrapper.like(DeviceContactModelDO::getTypeName, "产能") .eq(DeviceContactModelDO::getTypeName, "产能")
.or().like(DeviceContactModelDO::getAttributeType, "产能")
.or().like(DeviceContactModelDO::getAttributeName, "产能"))
.orderByAsc(DeviceContactModelDO::getDeviceId) .orderByAsc(DeviceContactModelDO::getDeviceId)
.orderByAsc(DeviceContactModelDO::getSort) .orderByDesc(DeviceContactModelDO::getCreateTime)
.orderByAsc(DeviceContactModelDO::getId)); .orderByDesc(DeviceContactModelDO::getId));
return points.stream().collect(Collectors.groupingBy(DeviceContactModelDO::getDeviceId, LinkedHashMap::new, Collectors.toList())); return points.stream().collect(Collectors.toMap(DeviceContactModelDO::getDeviceId, item -> item, (first, second) -> first,
LinkedHashMap::new));
} }
private DeviceProductionDailyReportRespVO.DeviceCapacityItem buildEmptyCapacityItem(DeviceDO device) { private DeviceProductionDailyReportRespVO.DeviceCapacityItem buildEmptyCapacityItem(DeviceDO device) {
@ -212,36 +224,238 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
@SneakyThrows @SneakyThrows
private byte[] buildExcel(DeviceProductionDailyReportGenerateReqVO reqVO, WorkTeamRespDTO workTeam, private byte[] buildExcel(DeviceProductionDailyReportGenerateReqVO reqVO, WorkTeamRespDTO workTeam,
LocalDateTime startTime, LocalDateTime endTime, LocalDateTime startTime, LocalDateTime endTime,
List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items) { List<DeviceProductionDailyReportRespVO.DeviceCapacityItem> items, List<Long> deviceIds) {
try (InputStream inputStream = new ClassPathResource(TEMPLATE_PATH).getInputStream(); try (InputStream inputStream = new ClassPathResource(TEMPLATE_PATH).getInputStream();
Workbook workbook = WorkbookFactory.create(inputStream); Workbook workbook = WorkbookFactory.create(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
Sheet sheet = workbook.getSheetAt(0); Sheet sheet = workbook.getSheetAt(0);
setCellValue(sheet, 2, 0, "日期:" + LocalDate.now().format(DATE_FORMATTER)); setReportColumnWidths(sheet);
setCellValue(sheet, 2, 4, "班次:" + StrUtil.blankToDefault(workTeam.getTeamName(), "")); log.info("[production-daily-report] template loaded: path={}, sheetName={}, mergedRegions={}",
setCellValue(sheet, 19, 9, "审核:"); TEMPLATE_PATH, sheet.getSheetName(), sheet.getMergedRegions());
String dateText = "日期:" + reqVO.getReportDate().format(DATE_FORMATTER);
int rowIndex = 5; String shiftText = "班次:" + StrUtil.blankToDefault(workTeam.getTeamName(), "");
setHeaderValue(sheet, "日期:", dateText, 2, 0);
setHeaderValue(sheet, "班次:", shiftText, 2, 4);
log.info("[production-daily-report] header cells after write: A3={}, C3={}, E3={}",
getCellValue(sheet, 2, 0), getCellValue(sheet, 2, 2), getCellValue(sheet, 2, 4));
int rowIndex = 4;
int exceptionStartRowIndex = 5;
Row templateRow = sheet.getRow(rowIndex);
if (items.size() > 1) {
sheet.shiftRows(exceptionStartRowIndex, sheet.getLastRowNum(), items.size() - 1, true, false);
}
for (int index = 0; index < items.size(); index++) { for (int index = 0; index < items.size(); index++) {
if (rowIndex + index > 9) {
sheet.shiftRows(10, sheet.getLastRowNum(), 1, true, false);
}
Row row = sheet.getRow(rowIndex + index); Row row = sheet.getRow(rowIndex + index);
if (row == null) { if (row == null) {
row = sheet.createRow(rowIndex + index); row = sheet.createRow(rowIndex + index);
copyRowStyle(templateRow, row, 5);
} }
DeviceProductionDailyReportRespVO.DeviceCapacityItem item = items.get(index); DeviceProductionDailyReportRespVO.DeviceCapacityItem item = items.get(index);
setCellValue(row, 0, index + 1); setCellValue(row, 0, index + 1);
setCellValue(row, 1, StrUtil.blankToDefault(item.getDeviceCode(), item.getDeviceName())); setCellValue(row, 1, buildDeviceText(item.getDeviceName(), item.getDeviceCode()));
setCellValue(row, 4, item.getCapacityName()); setCellValue(row, 2, buildCapacityPointText(item));
setCellValue(row, 20, item.getCapacityDiff()); setCellValue(row, 3, item.getCapacityDiff());
setCellValue(row, 21, toHour(startTime, endTime)); setCellValue(row, 4, startTime.toLocalTime() + "-" + endTime.toLocalTime());
setCellValue(row, 22, startTime.toLocalTime() + "-" + endTime.toLocalTime());
setCellValue(row, 24, workTeam.getTeamName());
} }
fillWarningDescription(sheet, rowIndex + items.size() + 2, deviceIds, startTime, endTime);
workbook.write(outputStream); workbook.write(outputStream);
return outputStream.toByteArray(); byte[] bytes = outputStream.toByteArray();
logGeneratedHeader(bytes);
return bytes;
}
}
private void fillWarningDescription(Sheet sheet, int warningRowIndex, List<Long> deviceIds,
LocalDateTime startTime, LocalDateTime endTime) {
List<DeviceWarinningRecordDO> warningRecords = tDengineService.selectDeviceWarningList(deviceIds, startTime, endTime);
Map<Long, List<DeviceWarinningRecordDO>> warningMap = warningRecords.stream()
.collect(Collectors.groupingBy(DeviceWarinningRecordDO::getDeviceId, LinkedHashMap::new, Collectors.toList()));
Map<String, String> alarmLevelLabelMap = buildAlarmLevelLabelMap();
Row templateRow = sheet.getRow(warningRowIndex);
for (int index = 0; index < deviceIds.size(); index++) {
Row row = sheet.getRow(warningRowIndex + index);
if (row == null) {
row = sheet.createRow(warningRowIndex + index);
copyRowStyle(templateRow, row, 5);
}
mergeCellsIfAbsent(sheet, warningRowIndex + index, 2, 4);
Long deviceId = deviceIds.get(index);
setCellValue(row, 0, index + 1);
setCellValue(row, 1, getDeviceText(deviceId));
String warningDescription = buildWarningDescription(warningMap.getOrDefault(deviceId, Collections.emptyList()), alarmLevelLabelMap);
setCellValue(row, 2, warningDescription);
setWrapText(row, 2);
row.setHeightInPoints(Math.max(row.getHeightInPoints(), 18F * Math.max(1, warningDescription.split("\n", -1).length)));
}
removeRowsFromEnd(sheet, warningRowIndex + deviceIds.size());
}
private void setReportColumnWidths(Sheet sheet) {
sheet.setColumnWidth(0, 8 * 256);
sheet.setColumnWidth(1, 32 * 256);
sheet.setColumnWidth(2, 52 * 256);
sheet.setColumnWidth(3, 14 * 256);
sheet.setColumnWidth(4, 22 * 256);
}
private String buildCapacityPointText(DeviceProductionDailyReportRespVO.DeviceCapacityItem item) {
String capacityName = item.getCapacityName();
String capacityCode = item.getCapacityCode();
if (StringUtils.isBlank(capacityName)) {
return StrUtil.blankToDefault(capacityCode, "");
}
if (StringUtils.isBlank(capacityCode) || StringUtils.equals(capacityName, capacityCode)) {
return capacityName;
}
return capacityName + "" + capacityCode + "";
}
private String getDeviceText(Long deviceId) {
DeviceDO device = deviceMapper.selectById(deviceId);
if (device == null) {
return "";
} }
return buildDeviceText(device.getDeviceName(), device.getDeviceCode());
}
private String buildDeviceText(String deviceName, String deviceCode) {
if (StringUtils.isBlank(deviceName)) {
return StrUtil.blankToDefault(deviceCode, "");
}
if (StringUtils.isBlank(deviceCode)) {
return deviceName;
}
return deviceName + "" + deviceCode + "";
}
private String buildWarningDescription(List<DeviceWarinningRecordDO> warningRecords, Map<String, String> alarmLevelLabelMap) {
if (CollUtil.isEmpty(warningRecords)) {
return "";
}
return warningRecords.stream()
.collect(Collectors.groupingBy(this::getWarningPointName, LinkedHashMap::new, Collectors.toList()))
.entrySet().stream()
.map(entry -> entry.getKey() + "" + buildWarningPointSummary(entry.getValue(), alarmLevelLabelMap))
.collect(Collectors.joining("\n"));
}
private String buildWarningPointSummary(List<DeviceWarinningRecordDO> warningRecords, Map<String, String> alarmLevelLabelMap) {
return warningRecords.stream()
.collect(Collectors.groupingBy(this::getWarningRuleKey, LinkedHashMap::new, Collectors.toList()))
.values().stream()
.map(records -> buildWarningRuleSummary(records, alarmLevelLabelMap))
.collect(Collectors.joining(""));
}
private String getWarningRuleKey(DeviceWarinningRecordDO record) {
return getWarningName(record) + "|" + StrUtil.blankToDefault(record.getAlarmLevel(), "");
}
private String buildWarningRuleSummary(List<DeviceWarinningRecordDO> warningRecords, Map<String, String> alarmLevelLabelMap) {
DeviceWarinningRecordDO firstRecord = warningRecords.get(0);
String levelText = buildAlarmLevelText(firstRecord.getAlarmLevel(), alarmLevelLabelMap);
return getWarningName(firstRecord) + warningRecords.size() + "次"
+ buildWarningValueRangeText(warningRecords) + levelText + buildWarningTimeRangeText(warningRecords);
}
private String buildAlarmLevelText(String alarmLevel, Map<String, String> alarmLevelLabelMap) {
if (StringUtils.isBlank(alarmLevel)) {
return "";
}
String alarmLevelLabel = alarmLevelLabelMap.get(normalizeAlarmLevel(alarmLevel));
return ",等级=" + StrUtil.blankToDefault(alarmLevelLabel, alarmLevel);
}
private Map<String, String> buildAlarmLevelLabelMap() {
List<DictDataRespDTO> dictDataList = dictDataApi.getDictDataList(ALARM_LEVEL_DICT_TYPE);
if (CollUtil.isEmpty(dictDataList)) {
return Collections.emptyMap();
}
Map<String, String> alarmLevelLabelMap = new LinkedHashMap<>();
for (DictDataRespDTO dictData : dictDataList) {
if (dictData == null || StringUtils.isBlank(dictData.getValue())) {
continue;
}
alarmLevelLabelMap.put(normalizeAlarmLevel(dictData.getValue()), dictData.getLabel());
}
return alarmLevelLabelMap;
}
private String normalizeAlarmLevel(String alarmLevel) {
String value = StringUtils.trimToEmpty(alarmLevel);
if (StringUtils.isBlank(value)) {
return "";
}
try {
return BigDecimal.valueOf(Double.parseDouble(value)).stripTrailingZeros().toPlainString();
} catch (NumberFormatException e) {
return value;
}
}
private String getWarningPointName(DeviceWarinningRecordDO record) {
return StrUtil.blankToDefault(record.getModelName(),
StrUtil.blankToDefault(record.getRuleName(), StrUtil.blankToDefault(record.getRule(), "未知点位")));
}
private String getWarningName(DeviceWarinningRecordDO record) {
return StrUtil.blankToDefault(record.getRuleName(), StrUtil.blankToDefault(record.getRule(), "告警"));
}
private String buildWarningValueRangeText(List<DeviceWarinningRecordDO> warningRecords) {
List<Double> values = warningRecords.stream()
.map(this::parseWarningValue)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (CollUtil.isEmpty(values)) {
return "";
}
double minValue = values.stream().min(Double::compareTo).orElse(0D);
double maxValue = values.stream().max(Double::compareTo).orElse(0D);
if (BigDecimal.valueOf(minValue).compareTo(BigDecimal.valueOf(maxValue)) == 0) {
return ",值=" + formatNumber(minValue);
}
return ",值=" + formatNumber(minValue) + "~" + formatNumber(maxValue);
}
private Double parseWarningValue(DeviceWarinningRecordDO record) {
if (StringUtils.isBlank(record.getAddressValue())) {
return null;
}
try {
return Double.valueOf(record.getAddressValue());
} catch (NumberFormatException e) {
return null;
}
}
private String buildWarningTimeRangeText(List<DeviceWarinningRecordDO> warningRecords) {
List<LocalDateTime> times = warningRecords.stream()
.map(DeviceWarinningRecordDO::getCreateTime)
.filter(Objects::nonNull)
.sorted()
.collect(Collectors.toList());
if (CollUtil.isEmpty(times)) {
return "";
}
LocalDateTime startTime = times.get(0);
LocalDateTime endTime = times.get(times.size() - 1);
if (Objects.equals(startTime, endTime)) {
return ",时间=" + formatWarningTime(startTime, startTime);
}
return ",时间=" + formatWarningTime(startTime, endTime) + "~" + formatWarningTime(endTime, startTime);
}
private String formatWarningTime(LocalDateTime time, LocalDateTime compareTime) {
if (Objects.equals(time.toLocalDate(), compareTime.toLocalDate())) {
return time.format(TIME_FORMATTER);
}
return time.format(DATE_TIME_FORMATTER);
}
private String formatNumber(Double value) {
return BigDecimal.valueOf(value).stripTrailingZeros().toPlainString();
} }
private DeviceProductionDailyReportRespVO convertFileToReport(FileDO file) { private DeviceProductionDailyReportRespVO convertFileToReport(FileDO file) {
@ -343,6 +557,11 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
} }
private void setCellValue(Sheet sheet, int rowIndex, int columnIndex, Object value) { private void setCellValue(Sheet sheet, int rowIndex, int columnIndex, Object value) {
CellRangeAddress mergedRegion = getMergedRegion(sheet, rowIndex, columnIndex);
if (mergedRegion != null) {
rowIndex = mergedRegion.getFirstRow();
columnIndex = mergedRegion.getFirstColumn();
}
Row row = sheet.getRow(rowIndex); Row row = sheet.getRow(rowIndex);
if (row == null) { if (row == null) {
row = sheet.createRow(rowIndex); row = sheet.createRow(rowIndex);
@ -361,5 +580,167 @@ public class DeviceProductionDailyReportServiceImpl implements DeviceProductionD
cell.setCellValue(value == null ? "" : value.toString()); cell.setCellValue(value == null ? "" : value.toString());
} }
} }
private void setWrapText(Row row, int columnIndex) {
Cell cell = row.getCell(columnIndex);
if (cell == null) {
return;
}
CellStyle cellStyle = row.getSheet().getWorkbook().createCellStyle();
cellStyle.cloneStyleFrom(cell.getCellStyle());
cellStyle.setWrapText(true);
cell.setCellStyle(cellStyle);
}
private void copyRowStyle(Row sourceRow, Row targetRow, int columnCount) {
if (sourceRow == null || targetRow == null) {
return;
}
targetRow.setHeight(sourceRow.getHeight());
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
Cell sourceCell = sourceRow.getCell(columnIndex);
if (sourceCell == null) {
continue;
}
Cell targetCell = targetRow.getCell(columnIndex);
if (targetCell == null) {
targetCell = targetRow.createCell(columnIndex);
}
targetCell.setCellStyle(sourceCell.getCellStyle());
}
}
private void mergeCellsIfAbsent(Sheet sheet, int rowIndex, int firstColumn, int lastColumn) {
CellRangeAddress newRegion = new CellRangeAddress(rowIndex, rowIndex, firstColumn, lastColumn);
for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
if (mergedRegion.intersects(newRegion)) {
return;
}
}
sheet.addMergedRegion(newRegion);
}
private void removeRowsFromEnd(Sheet sheet, int startRowIndex) {
int lastRowIndex = sheet.getLastRowNum();
if (startRowIndex > lastRowIndex) {
return;
}
for (int index = sheet.getNumMergedRegions() - 1; index >= 0; index--) {
CellRangeAddress mergedRegion = sheet.getMergedRegion(index);
if (mergedRegion.getFirstRow() >= startRowIndex) {
sheet.removeMergedRegion(index);
}
}
for (int rowIndex = lastRowIndex; rowIndex >= startRowIndex; rowIndex--) {
Row row = sheet.getRow(rowIndex);
if (row != null) {
sheet.removeRow(row);
}
}
}
private void setHeaderValue(Sheet sheet, String label, String value, int fallbackRowIndex, int fallbackColumnIndex) {
Cell labelCell = findCellByPrefix(sheet, label);
if (labelCell != null) {
CellRangeAddress mergedRegion = getMergedRegion(sheet, labelCell.getRowIndex(), labelCell.getColumnIndex());
log.info("[production-daily-report] set header by label: label={}, foundCell={}, rowIndex={}, columnIndex={}, mergedRegion={}, value={}",
label, labelCell.getAddress().formatAsString(), labelCell.getRowIndex(), labelCell.getColumnIndex(), mergedRegion, value);
setStringCellValueForce(sheet, labelCell.getRowIndex(), labelCell.getColumnIndex(), value);
return;
}
CellRangeAddress mergedRegion = getMergedRegion(sheet, fallbackRowIndex, fallbackColumnIndex);
log.info("[production-daily-report] set header by fallback: label={}, fallbackRowIndex={}, fallbackColumnIndex={}, mergedRegion={}, value={}",
label, fallbackRowIndex, fallbackColumnIndex, mergedRegion, value);
setStringCellValueForce(sheet, fallbackRowIndex, fallbackColumnIndex, value);
}
private void setStringCellValueForce(Sheet sheet, int rowIndex, int columnIndex, String value) {
CellRangeAddress mergedRegion = getMergedRegion(sheet, rowIndex, columnIndex);
int firstRowIndex = mergedRegion != null ? mergedRegion.getFirstRow() : rowIndex;
int firstColumnIndex = mergedRegion != null ? mergedRegion.getFirstColumn() : columnIndex;
Row row = sheet.getRow(firstRowIndex);
if (row == null) {
row = sheet.createRow(firstRowIndex);
}
Cell oldCell = row.getCell(firstColumnIndex);
org.apache.poi.ss.usermodel.CellStyle cellStyle = oldCell != null ? oldCell.getCellStyle() : null;
if (oldCell != null) {
row.removeCell(oldCell);
}
Cell newCell = row.createCell(firstColumnIndex, CellType.STRING);
if (cellStyle != null) {
newCell.setCellStyle(cellStyle);
}
newCell.setCellValue(value);
if (mergedRegion != null) {
for (int column = mergedRegion.getFirstColumn() + 1; column <= mergedRegion.getLastColumn(); column++) {
Cell mergedCell = row.getCell(column);
if (mergedCell != null) {
mergedCell.setCellValue("");
}
}
}
log.info("[production-daily-report] force set header cell: targetRowIndex={}, targetColumnIndex={}, mergedRegion={}, value={}, actualValue={}",
firstRowIndex, firstColumnIndex, mergedRegion, value, getCellValue(sheet, firstRowIndex, firstColumnIndex));
}
@SneakyThrows
private void logGeneratedHeader(byte[] bytes) {
try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(bytes))) {
Sheet sheet = workbook.getSheetAt(0);
log.info("[production-daily-report] generated bytes header check: A3={}, C3={}, E3={}, mergedRegions={}",
getCellValue(sheet, 2, 0), getCellValue(sheet, 2, 2), getCellValue(sheet, 2, 4), sheet.getMergedRegions());
}
}
private String getCellValue(Sheet sheet, int rowIndex, int columnIndex) {
Row row = sheet.getRow(rowIndex);
Cell cell = row != null ? row.getCell(columnIndex) : null;
if (cell == null) {
CellRangeAddress mergedRegion = getMergedRegion(sheet, rowIndex, columnIndex);
if (mergedRegion != null) {
row = sheet.getRow(mergedRegion.getFirstRow());
cell = row != null ? row.getCell(mergedRegion.getFirstColumn()) : null;
}
}
if (row == null) {
return null;
}
if (cell == null) {
return null;
}
if (cell.getCellType() == CellType.STRING) {
return cell.getStringCellValue();
}
if (cell.getCellType() == CellType.NUMERIC) {
return String.valueOf(cell.getNumericCellValue());
}
if (cell.getCellType() == CellType.BOOLEAN) {
return String.valueOf(cell.getBooleanCellValue());
}
return cell.toString();
}
private Cell findCellByPrefix(Sheet sheet, String label) {
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.STRING && StringUtils.startsWith(cell.getStringCellValue(), label)) {
return cell;
}
}
}
return null;
}
private CellRangeAddress getMergedRegion(Sheet sheet, int rowIndex, int columnIndex) {
for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
if (mergedRegion.isInRange(rowIndex, columnIndex)) {
return mergedRegion;
}
}
return null;
}
} }

@ -2662,6 +2662,40 @@ public class TDengineService {
} }
} }
/**
*
*/
@DS("tdengine")
public List<DeviceWarinningRecordDO> selectDeviceWarningList(List<Long> deviceIds, LocalDateTime startTime, LocalDateTime endTime) {
if (CollectionUtils.isEmpty(deviceIds)) {
return Collections.emptyList();
}
String placeholders = deviceIds.stream().map(item -> "?").collect(Collectors.joining(","));
StringBuilder sql = new StringBuilder();
List<Object> params = new ArrayList<>();
sql.append("SELECT * FROM ").append(tdengineTable("iot_device_warning_record")).append(" ")
.append("WHERE deleted = 0 ")
.append("AND device_id IN (").append(placeholders).append(") ");
params.addAll(deviceIds);
if (startTime != null) {
sql.append("AND create_time >= ? ");
params.add(Timestamp.valueOf(startTime));
}
if (endTime != null) {
sql.append("AND create_time <= ? ");
params.add(Timestamp.valueOf(endTime));
}
sql.append("ORDER BY device_id ASC, create_time ASC");
try {
return jdbcTemplate.query(sql.toString(), params.toArray(), (rs, rowNum) -> mapRowToWarningRecordDO(rs));
} catch (Exception e) {
log.error("查询设备时间段告警记录失败: deviceIds={}, startTime={}, endTime={}", deviceIds, startTime, endTime, e);
return Collections.emptyList();
}
}
/** /**
* *
*/ */

@ -24,6 +24,9 @@ public class DeviceLedgerPageRespVO {
@Schema(description = "停用数量 (deviceStatus=1)") @Schema(description = "停用数量 (deviceStatus=1)")
private Long disabledCount; private Long disabledCount;
@Schema(description = "维修数量 (deviceStatus=2)")
private Long repairCount;
@Schema(description = "已排产数量 (isScheduled=1)") @Schema(description = "已排产数量 (isScheduled=1)")
private Long scheduledCount; private Long scheduledCount;

@ -202,7 +202,7 @@ public class TaskController {
@GetMapping("/trend") @GetMapping("/trend")
@Operation(summary = "任务单趋势统计") @Operation(summary = "任务单趋势统计")
@PreAuthorize("@ss.hasPermission('mes:task:query')") // @PreAuthorize("@ss.hasPermission('mes:task:query')")
public CommonResult<TaskTrendRespVO> getTaskTrend(@Valid TaskTrendReqVO reqVO) { public CommonResult<TaskTrendRespVO> getTaskTrend(@Valid TaskTrendReqVO reqVO) {
return success(taskService.getTaskTrend(reqVO)); return success(taskService.getTaskTrend(reqVO));
} }

@ -520,6 +520,7 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
respVO.setAllCount(0L); respVO.setAllCount(0L);
respVO.setNormalCount(0L); respVO.setNormalCount(0L);
respVO.setDisabledCount(0L); respVO.setDisabledCount(0L);
respVO.setRepairCount(0L);
respVO.setScheduledCount(0L); respVO.setScheduledCount(0L);
respVO.setUnscheduledCount(0L); respVO.setUnscheduledCount(0L);
return respVO; return respVO;
@ -537,6 +538,7 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
respVO.setAllCount(0L); respVO.setAllCount(0L);
respVO.setNormalCount(0L); respVO.setNormalCount(0L);
respVO.setDisabledCount(0L); respVO.setDisabledCount(0L);
respVO.setRepairCount(0L);
respVO.setScheduledCount(0L); respVO.setScheduledCount(0L);
respVO.setUnscheduledCount(0L); respVO.setUnscheduledCount(0L);
return respVO; return respVO;
@ -545,6 +547,7 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
respVO.setAllCount((long) allList.size()); respVO.setAllCount((long) allList.size());
respVO.setNormalCount(allList.stream().filter(item -> item.getDeviceStatus() != null && item.getDeviceStatus() == 0).count()); respVO.setNormalCount(allList.stream().filter(item -> item.getDeviceStatus() != null && item.getDeviceStatus() == 0).count());
respVO.setDisabledCount(allList.stream().filter(item -> item.getDeviceStatus() != null && item.getDeviceStatus() == 1).count()); respVO.setDisabledCount(allList.stream().filter(item -> item.getDeviceStatus() != null && item.getDeviceStatus() == 1).count());
respVO.setRepairCount(allList.stream().filter(item -> item.getDeviceStatus() != null && item.getDeviceStatus() == 2).count());
respVO.setScheduledCount(allList.stream().filter(item -> item.getIsScheduled() != null && item.getIsScheduled() == 1).count()); respVO.setScheduledCount(allList.stream().filter(item -> item.getIsScheduled() != null && item.getIsScheduled() == 1).count());
respVO.setUnscheduledCount(allList.stream().filter(item -> item.getIsScheduled() != null && item.getIsScheduled() == 0).count()); respVO.setUnscheduledCount(allList.stream().filter(item -> item.getIsScheduled() != null && item.getIsScheduled() == 0).count());
return respVO; return respVO;

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO; import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO; import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldBrandMapper; import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldBrandMapper;
import cn.iocoder.yudao.module.common.enums.MoldBrandStatusEnum;
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil; import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
import cn.iocoder.yudao.module.mes.controller.admin.dashboard.vo.dashboard.EventStatisticsVO; import cn.iocoder.yudao.module.mes.controller.admin.dashboard.vo.dashboard.EventStatisticsVO;
import cn.iocoder.yudao.module.common.controller.admin.moldrepair.enums.RepairResultEnum; import cn.iocoder.yudao.module.common.controller.admin.moldrepair.enums.RepairResultEnum;
@ -91,6 +92,7 @@ public class MoldRepairServiceImpl implements MoldRepairService {
// 插入 // 插入
MoldRepairDO moldRepair = BeanUtils.toBean(createReqVO, MoldRepairDO.class); MoldRepairDO moldRepair = BeanUtils.toBean(createReqVO, MoldRepairDO.class);
moldRepairMapper.insert(moldRepair); moldRepairMapper.insert(moldRepair);
updateMoldBrandStatus(moldRepair.getMoldId(), MoldBrandStatusEnum.REPAIRING.getStatus());
sendCreateNotifyMessage(moldRepair); sendCreateNotifyMessage(moldRepair);
// 插入子表 // 插入子表
@ -124,7 +126,7 @@ public class MoldRepairServiceImpl implements MoldRepairService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateMoldRepair(MoldRepairSaveReqVO updateReqVO) { public void updateMoldRepair(MoldRepairSaveReqVO updateReqVO) {
// 校验存在 // 校验存在
validateMoldRepairExists(updateReqVO.getId()); MoldRepairDO oldMoldRepair = validateMoldRepairExists(updateReqVO.getId());
//编码重复判断 //编码重复判断
Long count = moldRepairMapper.selectCount(new LambdaQueryWrapper<MoldRepairDO>() Long count = moldRepairMapper.selectCount(new LambdaQueryWrapper<MoldRepairDO>()
@ -140,6 +142,8 @@ public class MoldRepairServiceImpl implements MoldRepairService {
// 更新 // 更新
MoldRepairDO updateObj = BeanUtils.toBean(updateReqVO, MoldRepairDO.class); MoldRepairDO updateObj = BeanUtils.toBean(updateReqVO, MoldRepairDO.class);
moldRepairMapper.updateById(updateObj); moldRepairMapper.updateById(updateObj);
Long moldId = updateReqVO.getMoldId() != null ? updateReqVO.getMoldId() : oldMoldRepair.getMoldId();
updateMoldBrandStatusByRepairResult(moldId, updateReqVO.getRepairStatus());
// 更新子表 // 更新子表
// updateMoldRepairLineList(updateReqVO.getId(), updateReqVO.getMoldRepairLines()); // updateMoldRepairLineList(updateReqVO.getId(), updateReqVO.getMoldRepairLines());
@ -159,10 +163,12 @@ public class MoldRepairServiceImpl implements MoldRepairService {
} }
private void validateMoldRepairExists(Long id) { private MoldRepairDO validateMoldRepairExists(Long id) {
if (moldRepairMapper.selectById(id) == null) { MoldRepairDO moldRepair = moldRepairMapper.selectById(id);
if (moldRepair == null) {
throw exception(MOLD_REPAIR_NOT_EXISTS); throw exception(MOLD_REPAIR_NOT_EXISTS);
} }
return moldRepair;
} }
@Override @Override
@ -304,6 +310,7 @@ public class MoldRepairServiceImpl implements MoldRepairService {
moldRepairDO.setConfirmDate(updateReqVO.getConfirmDate()); moldRepairDO.setConfirmDate(updateReqVO.getConfirmDate());
moldRepairDO.setRepairResult(updateReqVO.getRepairResult()); moldRepairDO.setRepairResult(updateReqVO.getRepairResult());
moldRepairMapper.updateById(moldRepairDO); moldRepairMapper.updateById(moldRepairDO);
updateMoldBrandStatusByRepairResult(moldRepairDO.getMoldId(), updateReqVO.getRepairResult());
batchUpdateTicketResults(updateReqVO.getUpdateReqVOList()); batchUpdateTicketResults(updateReqVO.getUpdateReqVOList());
} }
@ -457,14 +464,49 @@ public class MoldRepairServiceImpl implements MoldRepairService {
.anyMatch(vo -> vo.getResult() != null && vo.getResult().equals(JobResultEnum.FAIL.getCode())); .anyMatch(vo -> vo.getResult() != null && vo.getResult().equals(JobResultEnum.FAIL.getCode()));
if (hasFail) { if (hasFail) {
moldRepairDO.setRepairStatus(JobResultEnum.FAIL.getCode()); moldRepairDO.setRepairStatus(JobResultEnum.FAIL.getCode());
updateMoldBrandStatus(moldRepairDO.getMoldId(), MoldBrandStatusEnum.REPAIRING.getStatus());
} else { } else {
moldRepairDO.setRepairStatus(JobResultEnum.PASS.getCode()); moldRepairDO.setRepairStatus(JobResultEnum.PASS.getCode());
updateMoldBrandStatus(moldRepairDO.getMoldId(), MoldBrandStatusEnum.STANDBY.getStatus());
} }
moldRepairMapper.updateById(moldRepairDO); moldRepairMapper.updateById(moldRepairDO);
} }
private void updateMoldBrandStatusByRepairResult(Long moldId, String repairResult) {
if (StringUtils.isEmpty(repairResult)) {
return;
}
Integer status = isRepairPassed(repairResult)
? MoldBrandStatusEnum.STANDBY.getStatus()
: MoldBrandStatusEnum.REPAIRING.getStatus();
updateMoldBrandStatus(moldId, status);
}
private boolean isRepairPassed(String repairResult) {
String value = repairResult.trim();
return RepairResultEnum.PASS.getCode().toString().equals(value)
|| RepairResultEnum.PASS.getDesc().equalsIgnoreCase(value)
|| JobResultEnum.PASS.getCode().toString().equals(value)
|| "PASS".equalsIgnoreCase(value)
|| "通过".equals(value);
}
private void updateMoldBrandStatus(Long moldId, Integer status) {
if (moldId == null || status == null) {
return;
}
MoldBrandDO moldBrand = moldBrandMapper.selectById(moldId);
if (moldBrand == null) {
throw exception(MOLD_SET_NOT_EXISTS);
}
MoldBrandDO updateObj = new MoldBrandDO();
updateObj.setId(moldId);
updateObj.setStatus(status);
moldBrandMapper.updateById(updateObj);
}
private void validateBatchUpdateData(List<MoldRepairLineSaveReqVO> updateReqVOList) { private void validateBatchUpdateData(List<MoldRepairLineSaveReqVO> updateReqVOList) {

@ -66,9 +66,10 @@ public class DictDataController {
@GetMapping(value = {"/list-all-simple", "simple-list"}) @GetMapping(value = {"/list-all-simple", "simple-list"})
@Operation(summary = "获得全部字典数据列表", description = "一般用于管理后台缓存字典数据在本地") @Operation(summary = "获得全部字典数据列表", description = "一般用于管理后台缓存字典数据在本地")
// 无需添加权限认证,因为前端全局都需要 // 无需添加权限认证,因为前端全局都需要
public CommonResult<List<DictDataSimpleRespVO>> getSimpleDictDataList() { public CommonResult<List<DictDataSimpleRespVO>> getSimpleDictDataList(
@RequestParam(value = "dictType", required = false) String dictType) {
List<DictDataDO> list = dictDataService.getDictDataList( List<DictDataDO> list = dictDataService.getDictDataList(
CommonStatusEnum.ENABLE.getStatus(), null); CommonStatusEnum.ENABLE.getStatus(), dictType);
return success(BeanUtils.toBean(list, DictDataSimpleRespVO.class)); return success(BeanUtils.toBean(list, DictDataSimpleRespVO.class));
} }

@ -29,6 +29,8 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - App用户导航菜单配置") @Tag(name = "管理后台 - App用户导航菜单配置")
@RestController @RestController
@RequestMapping("/system/user-nav-menu") @RequestMapping("/system/user-nav-menu")
@ -56,8 +58,9 @@ public class UserNavMenuController {
@PutMapping("/update-list") @PutMapping("/update-list")
@Operation(summary = "批量更新") @Operation(summary = "批量更新")
// @PreAuthorize("@ss.hasPermission('system:user-nav-menu:update')") // @PreAuthorize("@ss.hasPermission('system:user-nav-menu:update')")
public CommonResult<Boolean> updateUserNavMenuList(@Valid @RequestBody List<UserNavMenuSaveReqVO> updateReqVOList) { public CommonResult<Boolean> updateUserNavMenuList(@RequestParam(value = "userId", required = false) Long userId,
userNavMenuService.updateUserNavMenuList(updateReqVOList); @Valid @RequestBody(required = false) List<UserNavMenuSaveReqVO> updateReqVOList) {
userNavMenuService.updateUserNavMenuList(userId != null ? userId : getLoginUserId(), updateReqVOList);
return success(true); return success(true);
} }

@ -55,7 +55,7 @@ public interface UserNavMenuService {
List<UserNavMenuDO> getUserNavMenuList(@Valid UserNavMenuPageReqVO listReqVO); List<UserNavMenuDO> getUserNavMenuList(@Valid UserNavMenuPageReqVO listReqVO);
void updateUserNavMenuList(@Valid List<UserNavMenuSaveReqVO> updateReqVOList); void updateUserNavMenuList(Long userId, @Valid List<UserNavMenuSaveReqVO> updateReqVOList);
} }

@ -47,17 +47,21 @@ public class UserNavMenuServiceImpl implements UserNavMenuService {
} }
@Override @Override
public void updateUserNavMenuList(List<UserNavMenuSaveReqVO> updateReqVOList) { public void updateUserNavMenuList(Long userId, List<UserNavMenuSaveReqVO> updateReqVOList) {
if (updateReqVOList == null || updateReqVOList.isEmpty()) { if (updateReqVOList == null || updateReqVOList.isEmpty()) {
if (userId == null) {
throw new IllegalArgumentException("userId cannot be empty when update menu list is empty");
}
userNavMenuMapper.deleteByUserId(userId);
return; return;
} }
Long userId = updateReqVOList.get(0).getUserId(); Long targetUserId = userId != null ? userId : updateReqVOList.get(0).getUserId();
for (UserNavMenuSaveReqVO updateReqVO : updateReqVOList) { for (UserNavMenuSaveReqVO updateReqVO : updateReqVOList) {
if (!Objects.equals(userId, updateReqVO.getUserId())) { if (!Objects.equals(targetUserId, updateReqVO.getUserId())) {
throw exception(USER_NAV_MENU_NOT_EXISTS); throw exception(USER_NAV_MENU_NOT_EXISTS);
} }
} }
userNavMenuMapper.deleteByUserId(userId); userNavMenuMapper.deleteByUserId(targetUserId);
List<UserNavMenuDO> insertList = BeanUtils.toBean(updateReqVOList, UserNavMenuDO.class); List<UserNavMenuDO> insertList = BeanUtils.toBean(updateReqVOList, UserNavMenuDO.class);
insertList.forEach(userNavMenuMapper::insert); insertList.forEach(userNavMenuMapper::insert);
} }

Loading…
Cancel
Save