refactor: 重构设备参数表查询逻辑以支持分表路由

master
zangch@mesnac.com 1 month ago
parent fe008bb747
commit c5d3f6e322

@ -4,7 +4,6 @@ import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.aucma.common.annotation.Anonymous;
import com.aucma.common.utils.DateUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -65,7 +64,7 @@ public class BaseDeviceParamValController extends BaseController {
*/
@PreAuthorize("@ss.hasPermi('baseDeviceParamVal:val:query')" )
@GetMapping(value = "/{recordId}" )
public AjaxResult getInfo(@PathVariable("recordId" ) Long recordId) {
public AjaxResult getInfo(@PathVariable("recordId" ) String recordId) {
return success(baseDeviceParamValService.selectBaseDeviceParamValByRecordId(recordId));
}
@ -96,7 +95,7 @@ public class BaseDeviceParamValController extends BaseController {
@PreAuthorize("@ss.hasPermi('baseDeviceParamVal:val:remove')" )
@Log(title = "设备工艺参数当前值" , businessType = BusinessType.DELETE)
@DeleteMapping("/{recordIds}" )
public AjaxResult remove(@PathVariable Long[] recordIds) {
public AjaxResult remove(@PathVariable String[] recordIds) {
return toAjax(baseDeviceParamValService.deleteBaseDeviceParamValByRecordIds(recordIds));
}

@ -1,6 +1,7 @@
package com.aucma.base.domain;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -18,7 +19,7 @@ public class BaseDeviceParamVal extends BaseEntity
private static final long serialVersionUID=1L;
/** 主键 */
private Long recordId;
private String recordId;
/** 参数编号 */
@Excel(name = "参数编号")
@ -55,12 +56,15 @@ private static final long serialVersionUID=1L;
/** 查询结束时间(仅查询用) */
private Date endTime;
public void setRecordId(Long recordId)
/** 查询涉及的月分表后缀(仅查询用) */
private List<String> tableSuffixes;
public void setRecordId(String recordId)
{
this.recordId = recordId;
}
public Long getRecordId()
public String getRecordId()
{
return recordId;
}
@ -144,6 +148,14 @@ private static final long serialVersionUID=1L;
this.endTime = endTime;
}
public List<String> getTableSuffixes() {
return tableSuffixes;
}
public void setTableSuffixes(List<String> tableSuffixes) {
this.tableSuffixes = tableSuffixes;
}
@Override
public String toString(){
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@ -157,6 +169,7 @@ public String toString(){
.append("recordTime",getRecordTime())
.append("beginTime",getBeginTime())
.append("endTime",getEndTime())
.append("tableSuffixes", getTableSuffixes())
.toString();
}
}

@ -4,6 +4,7 @@ import java.util.List;
import java.util.Map;
import com.aucma.base.domain.BaseDeviceParamVal;
import org.apache.ibatis.annotations.Param;
/**
* Mapper
@ -19,7 +20,7 @@ public interface BaseDeviceParamValMapper
* @param recordId
* @return
*/
public BaseDeviceParamVal selectBaseDeviceParamValByRecordId(Long recordId);
public BaseDeviceParamVal selectBaseDeviceParamValByRecordId(String recordId);
/**
*
@ -45,6 +46,16 @@ public interface BaseDeviceParamValMapper
*/
public int insertBaseDeviceParamVal(BaseDeviceParamVal baseDeviceParamVal);
/**
*
*
* @param tableName
* @param baseDeviceParamVal
* @return
*/
public int insertPartitionBaseDeviceParamVal(@Param("tableName") String tableName,
@Param("entity") BaseDeviceParamVal baseDeviceParamVal);
/**
*
*
@ -59,7 +70,7 @@ public interface BaseDeviceParamValMapper
* @param recordId
* @return
*/
public int deleteBaseDeviceParamValByRecordId(Long recordId);
public int deleteBaseDeviceParamValByRecordId(String recordId);
/**
*
@ -67,28 +78,28 @@ public interface BaseDeviceParamValMapper
* @param recordIds
* @return
*/
public int deleteBaseDeviceParamValByRecordIds(Long[] recordIds);
public int deleteBaseDeviceParamValByRecordIds(String[] recordIds);
/**
*
*
* @return Map
*/
public Map<String, Object> selectDeviceStatusStatistics();
public Map<String, Object> selectDeviceStatusStatistics(Map<String, Object> params);
/**
*
*
* @return
*/
public List<Map<String, Object>> selectDeviceStatusList();
public List<Map<String, Object>> selectDeviceStatusList(Map<String, Object> params);
/**
*
*
* @return
*/
public List<Map<String, Object>> selectDeviceStartTimeList();
public List<Map<String, Object>> selectDeviceStartTimeList(Map<String, Object> params);
/**
*
@ -106,6 +117,14 @@ public interface BaseDeviceParamValMapper
*/
public List<Double> selectParamHistoryValues(Map<String, Object> params);
/**
*
*
* @param params
* @return
*/
public String selectParamNameByCodeFromSources(Map<String, Object> params);
/**
*
*

@ -19,7 +19,7 @@ public interface IBaseDeviceParamValService
* @param recordId
* @return
*/
public BaseDeviceParamVal selectBaseDeviceParamValByRecordId(Long recordId);
public BaseDeviceParamVal selectBaseDeviceParamValByRecordId(String recordId);
/**
*
@ -59,7 +59,7 @@ public interface IBaseDeviceParamValService
* @param recordIds
* @return
*/
public int deleteBaseDeviceParamValByRecordIds(Long[] recordIds);
public int deleteBaseDeviceParamValByRecordIds(String[] recordIds);
/**
*
@ -67,7 +67,7 @@ public interface IBaseDeviceParamValService
* @param recordId
* @return
*/
public int deleteBaseDeviceParamValByRecordId(Long recordId);
public int deleteBaseDeviceParamValByRecordId(String recordId);
/**
*

@ -1,231 +1,184 @@
package com.aucma.base.service.impl;
import java.util.*;
import com.aucma.base.domain.BaseDeviceParamVal;
import com.aucma.base.mapper.BaseDeviceParamValMapper;
import com.aucma.base.service.IBaseDeviceParamValService;
import com.aucma.base.service.IRtDailyProdStateService;
import com.aucma.base.support.DeviceParamTableRouter;
import com.aucma.common.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.aucma.base.mapper.BaseDeviceParamValMapper;
import com.aucma.base.domain.BaseDeviceParamVal;
import com.aucma.base.service.IBaseDeviceParamValService;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* Service
*
* @author zch
* @date 2025-10-15
*/
@Service
public class BaseDeviceParamValServiceImpl implements IBaseDeviceParamValService
{
public class BaseDeviceParamValServiceImpl implements IBaseDeviceParamValService {
private static final Logger log = LoggerFactory.getLogger(BaseDeviceParamValServiceImpl.class);
private static final String DAILY_OUTPUT_PARAM_NAME = "机台状态-实际产出数量";
private static final DateTimeFormatter QUERY_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Autowired
private BaseDeviceParamValMapper baseDeviceParamValMapper;
/**
*
*
* @param recordId
* @return
*/
@Autowired
private DeviceParamTableRouter deviceParamTableRouter;
@Autowired
private IRtDailyProdStateService rtDailyProdStateService;
@Override
public BaseDeviceParamVal selectBaseDeviceParamValByRecordId(Long recordId)
{
public BaseDeviceParamVal selectBaseDeviceParamValByRecordId(String recordId) {
return baseDeviceParamValMapper.selectBaseDeviceParamValByRecordId(recordId);
}
/**
*
*
* @param baseDeviceParamVal
* @return
*/
@Override
public List<BaseDeviceParamVal> selectBaseDeviceParamValList(BaseDeviceParamVal baseDeviceParamVal)
{
public List<BaseDeviceParamVal> selectBaseDeviceParamValList(BaseDeviceParamVal baseDeviceParamVal) {
return baseDeviceParamValMapper.selectBaseDeviceParamValList(baseDeviceParamVal);
}
/**
*
*
* @param baseDeviceParamVal
* @return
*/
@Override
public List<BaseDeviceParamVal> selectLatestBaseDeviceParamValList(BaseDeviceParamVal baseDeviceParamVal)
{
public List<BaseDeviceParamVal> selectLatestBaseDeviceParamValList(BaseDeviceParamVal baseDeviceParamVal) {
try {
// 入参为空直接返回,调用侧可据此判定为无效请求
if (baseDeviceParamVal == null) {
if (baseDeviceParamVal == null) {
baseDeviceParamVal = new BaseDeviceParamVal();
}
// 防止全表扫描若未指定时间范围默认查询最近24小时
if (baseDeviceParamVal.getBeginTime() == null && baseDeviceParamVal.getEndTime() == null) {
Date end = new Date();
Date begin = DateUtils.addHours(end, -24);
baseDeviceParamVal.setBeginTime(begin);
baseDeviceParamVal.setEndTime(end);
}
baseDeviceParamVal.setTableSuffixes(deviceParamTableRouter.resolveReadTableSuffixes(
baseDeviceParamVal.getBeginTime(), baseDeviceParamVal.getEndTime()));
List<BaseDeviceParamVal> list = baseDeviceParamValMapper.selectLatestBaseDeviceParamValList(baseDeviceParamVal);
return list != null ? list : Collections.emptyList();
} catch (Exception e) {
log.error("查询设备参数最新值失败: {}", e.getMessage());
log.error("查询设备参数最新值失败: {}", e.getMessage(), e);
return Collections.emptyList();
}
}
/**
*
*
* @param baseDeviceParamVal
* @return
*/
@Override
public int insertBaseDeviceParamVal(BaseDeviceParamVal baseDeviceParamVal)
{
// 当天无记录时再插入,兼容首次上报场景
return baseDeviceParamValMapper.insertBaseDeviceParamVal(baseDeviceParamVal);
@Transactional(rollbackFor = Exception.class)
public int insertBaseDeviceParamVal(BaseDeviceParamVal baseDeviceParamVal) {
if (baseDeviceParamVal == null) {
return 0;
}
fillTimeIfAbsent(baseDeviceParamVal);
String tableName = deviceParamTableRouter.resolveWriteTable(
baseDeviceParamVal.getDeviceCode(), baseDeviceParamVal.getCollectTime());
if ("BASE_DEVICE_PARAM_VAL".equals(tableName)) {
int rows = baseDeviceParamValMapper.insertBaseDeviceParamVal(baseDeviceParamVal);
syncRtStateIfNeeded(baseDeviceParamVal, rows);
return rows;
}
fillPartitionRecordIdIfAbsent(baseDeviceParamVal);
return baseDeviceParamValMapper.insertPartitionBaseDeviceParamVal(tableName, baseDeviceParamVal);
}
/**
*
*
* @param baseDeviceParamVal
* @return
*/
@Override
public int updateBaseDeviceParamVal(BaseDeviceParamVal baseDeviceParamVal)
{
public int updateBaseDeviceParamVal(BaseDeviceParamVal baseDeviceParamVal) {
return baseDeviceParamValMapper.updateBaseDeviceParamVal(baseDeviceParamVal);
}
/**
*
*
* @param recordIds
* @return
*/
@Override
public int deleteBaseDeviceParamValByRecordIds(Long[] recordIds)
{
public int deleteBaseDeviceParamValByRecordIds(String[] recordIds) {
return baseDeviceParamValMapper.deleteBaseDeviceParamValByRecordIds(recordIds);
}
/**
*
*
* @param recordId
* @return
*/
@Override
public int deleteBaseDeviceParamValByRecordId(Long recordId)
{
public int deleteBaseDeviceParamValByRecordId(String recordId) {
return baseDeviceParamValMapper.deleteBaseDeviceParamValByRecordId(recordId);
}
/**
*
*
* @return Map
*/
@Override
public Map<String, Object> selectDeviceStatusStatistics()
{
public Map<String, Object> selectDeviceStatusStatistics() {
try {
Map<String, Object> result = baseDeviceParamValMapper.selectDeviceStatusStatistics();
Map<String, Object> params = buildRangeParams(DateUtils.addHours(new Date(), -2), new Date());
Map<String, Object> result = baseDeviceParamValMapper.selectDeviceStatusStatistics(params);
if (result == null) {
result = new HashMap<>();
result.put("totalCount", 0);//从base_deviceledger中获取is_flag = 1
result.put("runningCount", 0);//机台状态-三色灯机器运行
result.put("stoppedCount", 0);//三色灯机器暂停
result.put("standbyCount", 0);//三色灯机器待机
result.put("alarmCount", 0);//三色灯机器报警
result.put("notStartedCount", 0);//t.totalCount - s.runningCount - s.stoppedCount - s.standbyCount - s.alarmCount AS notStartedCount
result.put("runningRate", "0%");
return result;
result.put("TOTALCOUNT", 0);
result.put("RUNNINGCOUNT", 0);
result.put("STOPPEDCOUNT", 0);
result.put("STANDBYCOUNT", 0);
result.put("ALARMCOUNT", 0);
result.put("NOTSTARTEDCOUNT", 0);
}
// 计算开机率
Object totalObj = result.get("TOTALCOUNT");
Object runningObj = result.get("RUNNINGCOUNT");
int total = totalObj != null ? ((Number) totalObj).intValue() : 0;
int running = runningObj != null ? ((Number) runningObj).intValue() : 0;
int total = getIntValue(result.get("TOTALCOUNT"));
int running = getIntValue(result.get("RUNNINGCOUNT"));
String runningRate = total > 0 ? String.format("%.2f%%", (running * 100.0 / total)) : "0%";
result.put("runningRate", runningRate);
return result;
} catch (Exception e) {
log.error("查询设备状态统计失败: {}", e.getMessage());
log.error("查询设备状态统计失败: {}", e.getMessage(), e);
Map<String, Object> result = new HashMap<>();
result.put("totalCount", 0);
result.put("runningCount", 0);
result.put("stoppedCount", 0);
result.put("standbyCount", 0);
result.put("notStartedCount", 0);
result.put("TOTALCOUNT", 0);
result.put("RUNNINGCOUNT", 0);
result.put("STOPPEDCOUNT", 0);
result.put("STANDBYCOUNT", 0);
result.put("ALARMCOUNT", 0);
result.put("NOTSTARTEDCOUNT", 0);
result.put("runningRate", "0%");
return result;
}
}
/**
*
*
* @return
*/
@Override
public List<Map<String, Object>> selectDeviceStatusList()
{
public List<Map<String, Object>> selectDeviceStatusList() {
try {
List<Map<String, Object>> list = baseDeviceParamValMapper.selectDeviceStatusList();
Map<String, Object> params = buildRangeParams(DateUtils.addHours(new Date(), -2), new Date());
List<Map<String, Object>> list = baseDeviceParamValMapper.selectDeviceStatusList(params);
return list != null ? list : Collections.emptyList();
} catch (Exception e) {
log.error("查询设备状态列表失败: {}", e.getMessage());
log.error("查询设备状态列表失败: {}", e.getMessage(), e);
return Collections.emptyList();
}
}
/**
*
*
* @return
*/
@Override
public List<Map<String, Object>> selectDeviceStartTimeList()
{
public List<Map<String, Object>> selectDeviceStartTimeList() {
try {
List<Map<String, Object>> list = baseDeviceParamValMapper.selectDeviceStartTimeList();
Date now = new Date();
Map<String, Object> params = buildRangeParams(now, now);
List<Map<String, Object>> list = baseDeviceParamValMapper.selectDeviceStartTimeList(params);
return list != null ? list : Collections.emptyList();
} catch (Exception e) {
log.error("查询设备开机时间列表失败: {}", e.getMessage());
log.error("查询设备开机时间列表失败: {}", e.getMessage(), e);
return Collections.emptyList();
}
}
/**
*
*/
@Override
public List<BaseDeviceParamVal> selectTraceList(String deviceCode, String paramCode, String startTime, String endTime) {
try {
// mapper层使用Map入参便于只携带本次upsert所需字段
Map<String, Object> params = new HashMap<>();
params.put("deviceCode", deviceCode);
params.put("paramCode", paramCode);
params.put("startTime", startTime);
params.put("endTime", endTime);
Map<String, Object> params = buildStringRangeParams(deviceCode, paramCode, startTime, endTime);
List<BaseDeviceParamVal> list = baseDeviceParamValMapper.selectTraceList(params);
return list != null ? list : Collections.emptyList();
} catch (Exception e) {
log.error("参数追溯查询失败: {}", e.getMessage());
log.error("参数追溯查询失败: {}", e.getMessage(), e);
return Collections.emptyList();
}
}
/**
* SPC
*/
@Override
public Map<String, Object> getSPCData(String deviceCode, String paramCode, String startTime, String endTime) {
Map<String, Object> result = new HashMap<>();
@ -233,21 +186,13 @@ public class BaseDeviceParamValServiceImpl implements IBaseDeviceParamValService
result.put("paramCode", paramCode);
try {
// 查询参数名称
String paramName = baseDeviceParamValMapper.selectParamNameByCode(paramCode);
Map<String, Object> params = buildStringRangeParams(deviceCode, paramCode, startTime, endTime);
String paramName = baseDeviceParamValMapper.selectParamNameByCodeFromSources(params);
result.put("paramName", paramName != null ? paramName : paramCode);
// 查询参数历史值
// mapper层使用Map入参便于只携带本次upsert所需字段
Map<String, Object> params = new HashMap<>();
params.put("deviceCode", deviceCode);
params.put("paramCode", paramCode);
params.put("startTime", startTime);
params.put("endTime", endTime);
List<Double> values = baseDeviceParamValMapper.selectParamHistoryValues(params);
if (values == null || values.isEmpty()) {
result.put("values", new ArrayList<>());
result.put("values", Collections.emptyList());
result.put("sampleSize", 0);
result.put("mean", 0.0);
result.put("stdDev", 0.0);
@ -261,7 +206,6 @@ public class BaseDeviceParamValServiceImpl implements IBaseDeviceParamValService
result.put("values", values);
result.put("sampleSize", values.size());
// 计算统计指标
double mean = calculateMean(values);
double stdDev = calculateStdDev(values, mean);
double ucl = mean + 3 * stdDev;
@ -273,72 +217,139 @@ public class BaseDeviceParamValServiceImpl implements IBaseDeviceParamValService
result.put("lcl", Math.round(lcl * 1000.0) / 1000.0);
result.put("cl", Math.round(mean * 1000.0) / 1000.0);
// 计算CPK假设规格限为均值±10%
double usl = mean * 1.1;
double lsl = mean * 0.9;
double cpk = calculateCPK(mean, stdDev, usl, lsl);
result.put("cpk", Math.round(cpk * 100.0) / 100.0);
result.put("usl", Math.round(usl * 1000.0) / 1000.0);
result.put("lsl", Math.round(lsl * 1000.0) / 1000.0);
return result;
} catch (Exception e) {
log.error("获取SPC分析数据失败: {}", e.getMessage());
log.error("获取SPC分析数据失败: {}", e.getMessage(), e);
result.put("error", e.getMessage());
return result;
}
}
/**
*
*/
@Override
public int upsertTodayParamValue(BaseDeviceParamVal baseDeviceParamVal)
{
// 入参为空直接返回,调用侧可据此判定为无效请求
@Transactional(rollbackFor = Exception.class)
public int upsertTodayParamValue(BaseDeviceParamVal baseDeviceParamVal) {
if (baseDeviceParamVal == null) {
return 0;
}
// 若调用方未传时间统一回填服务端当前时间避免空时间导致SQL匹配偏差
Date now = new Date();
if (baseDeviceParamVal.getCollectTime() == null) {
baseDeviceParamVal.setCollectTime(now);
}
if (baseDeviceParamVal.getRecordTime() == null) {
baseDeviceParamVal.setRecordTime(now);
}
// WhyPDA上报需要沉淀完整过程数据后续分析依赖时间序列不能覆盖当天已有记录
return baseDeviceParamValMapper.insertBaseDeviceParamVal(baseDeviceParamVal);
fillTimeIfAbsent(baseDeviceParamVal);
return insertBaseDeviceParamVal(baseDeviceParamVal);
}
private void fillTimeIfAbsent(BaseDeviceParamVal entity) {
Date now = new Date();
if (entity.getCollectTime() == null) {
entity.setCollectTime(now);
}
if (entity.getRecordTime() == null) {
entity.setRecordTime(now);
}
}
private void fillPartitionRecordIdIfAbsent(BaseDeviceParamVal entity) {
if (entity.getRecordId() == null || entity.getRecordId().trim().isEmpty()) {
// 为什么这样做:自动采集月表要求字符串型业务唯一标识,手工补录时也要保持同一语义。
entity.setRecordId(UUID.randomUUID().toString());
}
}
private void syncRtStateIfNeeded(BaseDeviceParamVal entity, int rows) {
if (rows <= 0) {
return;
}
if (!deviceParamTableRouter.isOldDevice(entity.getDeviceCode())) {
return;
}
if (!DAILY_OUTPUT_PARAM_NAME.equals(entity.getParamName())) {
return;
}
try {
BigDecimal newVal = new BigDecimal(entity.getParamValue());
// 为什么这样做OLD 设备只走 Java 写入链路,不在这里同步 RT 就会让 Board4 永远少算 OLD 设备产量。
rtDailyProdStateService.incrementProduction(
entity.getDeviceCode(), entity.getParamName(), newVal, entity.getCollectTime());
} catch (NumberFormatException ex) {
log.warn("OLD设备产量值不是合法数字跳过RT同步 | deviceCode={}, paramValue={}",
entity.getDeviceCode(), entity.getParamValue());
}
}
private Map<String, Object> buildRangeParams(Date startTime, Date endTime) {
Map<String, Object> params = new HashMap<>();
params.put("tableSuffixes", deviceParamTableRouter.resolveReadTableSuffixes(startTime, endTime));
return params;
}
private Map<String, Object> buildStringRangeParams(String deviceCode, String paramCode, String startTime, String endTime) {
Map<String, Object> params = new HashMap<>();
params.put("deviceCode", deviceCode);
params.put("paramCode", paramCode);
params.put("startTime", startTime);
params.put("endTime", endTime);
params.put("tableSuffixes", deviceParamTableRouter.resolveReadTableSuffixes(
parseQueryDate(startTime), parseQueryDate(endTime)));
return params;
}
private Date parseQueryDate(String dateTime) {
if (dateTime == null || dateTime.trim().isEmpty()) {
return null;
}
LocalDateTime localDateTime = LocalDateTime.parse(dateTime.trim(), QUERY_TIME_FORMATTER);
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
private int getIntValue(Object value) {
if (value instanceof Number) {
return ((Number) value).intValue();
}
if (value == null) {
return 0;
}
try {
return Integer.parseInt(value.toString());
} catch (NumberFormatException ex) {
return 0;
}
}
private double calculateMean(List<Double> values) {
if (values == null || values.isEmpty()) return 0.0;
if (values == null || values.isEmpty()) {
return 0.0;
}
double sum = 0.0;
for (Double v : values) {
if (v != null) sum += v;
for (Double value : values) {
if (value != null) {
sum += value;
}
}
return sum / values.size();
}
private double calculateStdDev(List<Double> values, double mean) {
if (values == null || values.size() < 2) return 0.0;
if (values == null || values.size() < 2) {
return 0.0;
}
double sumSquares = 0.0;
for (Double v : values) {
if (v != null) {
sumSquares += Math.pow(v - mean, 2);
for (Double value : values) {
if (value != null) {
sumSquares += Math.pow(value - mean, 2);
}
}
return Math.sqrt(sumSquares / (values.size() - 1));
}
private double calculateCPK(double mean, double stdDev, double usl, double lsl) {
if (stdDev == 0) return 0.0;
double cpupper = (usl - mean) / (3 * stdDev);
double cplower = (mean - lsl) / (3 * stdDev);
return Math.min(cpupper, cplower);
if (stdDev == 0) {
return 0.0;
}
double cpUpper = (usl - mean) / (3 * stdDev);
double cpLower = (mean - lsl) / (3 * stdDev);
return Math.min(cpUpper, cpLower);
}
}

@ -9,6 +9,7 @@ import java.util.Set;
import com.aucma.base.domain.BaseMaterialInfo;
import com.aucma.base.domain.BaseOrderInfo;
import com.aucma.base.mapper.BaseOrderInfoMapper;
import com.aucma.base.service.IBusinessCodeGeneratorService;
import com.aucma.base.service.IBaseMaterialInfoService;
import com.aucma.base.service.IBaseOrderInfoService;
import com.aucma.common.exception.ServiceException;
@ -26,12 +27,17 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Service
public class BaseOrderInfoServiceImpl implements IBaseOrderInfoService {
private static final String DEFAULT_WORK_CENTER_CODE = "7";
@Autowired
private BaseOrderInfoMapper baseOrderInfoMapper;
@Autowired
private IBaseMaterialInfoService baseMaterialInfoService;
@Autowired
private IBusinessCodeGeneratorService businessCodeGeneratorService;
/**
*
*
@ -97,6 +103,7 @@ public class BaseOrderInfoServiceImpl implements IBaseOrderInfoService {
*/
@Override
public int insertBaseOrderInfo(BaseOrderInfo baseOrderInfo) {
fillInsertDefaults(baseOrderInfo);
syncMaterialMasterFields(baseOrderInfo);
baseOrderInfo.setCreatedTime(DateUtils.getNowDate());
return baseOrderInfoMapper.insertBaseOrderInfo(baseOrderInfo);
@ -110,6 +117,7 @@ public class BaseOrderInfoServiceImpl implements IBaseOrderInfoService {
*/
@Override
public int updateBaseOrderInfo(BaseOrderInfo baseOrderInfo) {
preserveOrderCodeOnUpdate(baseOrderInfo);
syncMaterialMasterFields(baseOrderInfo);
baseOrderInfo.setUpdatedTime(DateUtils.getNowDate());
return baseOrderInfoMapper.updateBaseOrderInfo(baseOrderInfo);
@ -361,4 +369,31 @@ public class BaseOrderInfoServiceImpl implements IBaseOrderInfoService {
baseOrderInfo.setMaterialName(materialInfo.getMaterialName());
baseOrderInfo.setMatkl(materialInfo.getMaterialMatkl());
}
private void fillInsertDefaults(BaseOrderInfo baseOrderInfo) {
if (baseOrderInfo == null) {
throw new ServiceException("工单信息不能为空");
}
// 为什么新增时一律由后端生成编号:只有服务端统一串行分配,才能在并发新增时避免同一编号被重复使用。
baseOrderInfo.setOrderCode(businessCodeGeneratorService.generateSapPlanCode(DateUtils.getNowDate()));
if (StringUtils.isBlank(baseOrderInfo.getWorkCenterCode())) {
// 为什么默认给工作中心 7满足当前业务默认值要求同时保留前端可改动能力未显式选择时也能稳定落库。
baseOrderInfo.setWorkCenterCode(DEFAULT_WORK_CENTER_CODE);
}
}
private void preserveOrderCodeOnUpdate(BaseOrderInfo baseOrderInfo) {
if (baseOrderInfo == null || baseOrderInfo.getObjId() == null) {
return;
}
if (StringUtils.isNotBlank(baseOrderInfo.getOrderCode())) {
baseOrderInfo.setOrderCode(baseOrderInfo.getOrderCode().trim());
return;
}
BaseOrderInfo existedOrder = baseOrderInfoMapper.selectBaseOrderInfoByObjId(baseOrderInfo.getObjId());
if (existedOrder == null) {
throw new ServiceException("工单不存在,无法更新");
}
baseOrderInfo.setOrderCode(existedOrder.getOrderCode());
}
}

@ -5,280 +5,461 @@
<mapper namespace="com.aucma.base.mapper.BaseDeviceParamValMapper">
<resultMap type="BaseDeviceParamVal" id="BaseDeviceParamValResult">
<result property="recordId" column="record_id" />
<result property="paramCode" column="param_code" />
<result property="deviceCode" column="device_code" />
<result property="deviceId" column="device_id" />
<result property="paramName" column="param_name" />
<result property="paramValue" column="param_value" />
<result property="collectTime" column="collect_time" />
<result property="recordTime" column="record_time" />
<result property="recordId" column="record_id"/>
<result property="paramCode" column="param_code"/>
<result property="deviceCode" column="device_code"/>
<result property="deviceId" column="device_id"/>
<result property="paramName" column="param_name"/>
<result property="paramValue" column="param_value"/>
<result property="collectTime" column="collect_time"/>
<result property="recordTime" column="record_time"/>
</resultMap>
<sql id="baseSelectColumns">
record_id || '' AS record_id, param_code, device_code, device_id,
param_name, param_value, collect_time, record_time
</sql>
<sql id="selectBaseDeviceParamValVo">
select record_id, param_code, device_code, device_id, param_name, param_value,
collect_time, record_time
from base_device_param_val
SELECT <include refid="baseSelectColumns"/>
FROM base_device_param_val
</sql>
<sql id="dualSourceFrom">
<trim suffixOverrides="UNION ALL">
SELECT <include refid="baseSelectColumns"/>
FROM BASE_DEVICE_PARAM_VAL
WHERE device_code LIKE 'OLD-%'
<if test="deviceCode != null and deviceCode != ''">
AND device_code = #{deviceCode}
</if>
<if test="paramCode != null and paramCode != ''">
AND param_code = #{paramCode}
</if>
<if test="deviceId != null">
AND device_id = #{deviceId}
</if>
<if test="paramName != null and paramName != ''">
AND param_name LIKE '%' || #{paramName} || '%'
</if>
<if test="beginTime != null and endTime != null">
AND NVL(record_time, collect_time) BETWEEN #{beginTime} AND #{endTime}
</if>
UNION ALL
<if test="tableSuffixes != null and tableSuffixes.size() > 0">
<foreach item="suffix" collection="tableSuffixes" separator=" UNION ALL ">
SELECT <include refid="baseSelectColumns"/>
FROM BASE_DEVICE_PARAM_VAL_${suffix}
WHERE device_code NOT LIKE 'OLD-%'
<if test="deviceCode != null and deviceCode != ''">
AND device_code = #{deviceCode}
</if>
<if test="paramCode != null and paramCode != ''">
AND param_code = #{paramCode}
</if>
<if test="deviceId != null">
AND device_id = #{deviceId}
</if>
<if test="paramName != null and paramName != ''">
AND param_name LIKE '%' || #{paramName} || '%'
</if>
<if test="beginTime != null and endTime != null">
AND NVL(record_time, collect_time) BETWEEN #{beginTime} AND #{endTime}
</if>
</foreach>
</if>
</trim>
</sql>
<select id="selectBaseDeviceParamValList" parameterType="BaseDeviceParamVal" resultMap="BaseDeviceParamValResult">
<include refid="selectBaseDeviceParamValVo"/>
<where>
<if test="paramCode != null and paramCode != ''"> and param_code = #{paramCode}</if>
<if test="deviceCode != null and deviceCode != ''"> and device_code = #{deviceCode}</if>
<if test="deviceId != null "> and device_id = #{deviceId}</if>
<if test="paramName != null and paramName != ''"> and param_name like concat(concat('%', #{paramName}), '%')</if>
<if test="paramValue != null and paramValue != ''"> and param_value = #{paramValue}</if>
<if test="collectTime != null "> and collect_time = #{collectTime}</if>
<if test="recordTime != null "> and record_time = #{recordTime}</if>
<if test="paramCode != null and paramCode != ''">and param_code = #{paramCode}</if>
<if test="deviceCode != null and deviceCode != ''">and device_code = #{deviceCode}</if>
<if test="deviceId != null">and device_id = #{deviceId}</if>
<if test="paramName != null and paramName != ''">and param_name like '%' || #{paramName} || '%'</if>
<if test="paramValue != null and paramValue != ''">and param_value = #{paramValue}</if>
<if test="collectTime != null">and collect_time = #{collectTime}</if>
<if test="recordTime != null">and record_time = #{recordTime}</if>
</where>
</select>
<select id="selectBaseDeviceParamValByRecordId" parameterType="Long" resultMap="BaseDeviceParamValResult">
<include refid="selectBaseDeviceParamValVo"/>
where record_id = #{recordId}
<select id="selectBaseDeviceParamValByRecordId" parameterType="java.lang.String" resultMap="BaseDeviceParamValResult">
<include refid="selectBaseDeviceParamValVo"/>
WHERE record_id = #{recordId}
</select>
<insert id="insertBaseDeviceParamVal" parameterType="BaseDeviceParamVal">
<selectKey keyProperty="recordId" resultType="long" order="BEFORE">
SELECT PARAMRECORD_SEQ_ID.NEXTVAL as recordId FROM DUAL
</selectKey>
insert into base_device_param_val
<selectKey keyProperty="recordId" resultType="string" order="BEFORE">
SELECT TO_CHAR(PARAMRECORD_SEQ_ID.NEXTVAL) AS recordId FROM DUAL
</selectKey>
INSERT INTO base_device_param_val
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="recordId != null">record_id,</if>
<if test="paramCode != null">param_code,</if>
<if test="deviceCode != null">device_code,</if>
<if test="deviceId != null">device_id,</if>
<if test="paramName != null">param_name,</if>
<if test="paramValue != null">param_value,</if>
<if test="collectTime != null">collect_time,</if>
<if test="recordTime != null">record_time,</if>
<if test="recordId != null">record_id,</if>
<if test="paramCode != null">param_code,</if>
<if test="deviceCode != null">device_code,</if>
<if test="deviceId != null">device_id,</if>
<if test="paramName != null">param_name,</if>
<if test="paramValue != null">param_value,</if>
<if test="collectTime != null">collect_time,</if>
<if test="recordTime != null">record_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="recordId != null">#{recordId},</if>
<if test="paramCode != null">#{paramCode},</if>
<if test="deviceCode != null">#{deviceCode},</if>
<if test="deviceId != null">#{deviceId},</if>
<if test="paramName != null">#{paramName},</if>
<if test="paramValue != null">#{paramValue},</if>
<if test="collectTime != null">#{collectTime},</if>
<if test="recordTime != null">#{recordTime},</if>
<if test="recordId != null">#{recordId},</if>
<if test="paramCode != null">#{paramCode},</if>
<if test="deviceCode != null">#{deviceCode},</if>
<if test="deviceId != null">#{deviceId},</if>
<if test="paramName != null">#{paramName},</if>
<if test="paramValue != null">#{paramValue},</if>
<if test="collectTime != null">#{collectTime},</if>
<if test="recordTime != null">#{recordTime},</if>
</trim>
</insert>
<insert id="insertPartitionBaseDeviceParamVal">
INSERT INTO ${tableName}
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="entity.recordId != null">record_id,</if>
<if test="entity.paramCode != null">param_code,</if>
<if test="entity.deviceCode != null">device_code,</if>
<if test="entity.deviceId != null">device_id,</if>
<if test="entity.paramName != null">param_name,</if>
<if test="entity.paramValue != null">param_value,</if>
<if test="entity.collectTime != null">collect_time,</if>
<if test="entity.recordTime != null">record_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="entity.recordId != null">#{entity.recordId},</if>
<if test="entity.paramCode != null">#{entity.paramCode},</if>
<if test="entity.deviceCode != null">#{entity.deviceCode},</if>
<if test="entity.deviceId != null">#{entity.deviceId},</if>
<if test="entity.paramName != null">#{entity.paramName},</if>
<if test="entity.paramValue != null">#{entity.paramValue},</if>
<if test="entity.collectTime != null">#{entity.collectTime},</if>
<if test="entity.recordTime != null">#{entity.recordTime},</if>
</trim>
</insert>
<update id="updateBaseDeviceParamVal" parameterType="BaseDeviceParamVal">
update base_device_param_val
UPDATE base_device_param_val
<trim prefix="SET" suffixOverrides=",">
<if test="paramCode != null">param_code = #{paramCode},</if>
<if test="deviceCode != null">device_code = #{deviceCode},</if>
<if test="deviceId != null">device_id = #{deviceId},</if>
<if test="paramName != null">param_name = #{paramName},</if>
<if test="paramValue != null">param_value = #{paramValue},</if>
<if test="collectTime != null">collect_time = #{collectTime},</if>
<if test="recordTime != null">record_time = #{recordTime},</if>
<if test="paramCode != null">param_code = #{paramCode},</if>
<if test="deviceCode != null">device_code = #{deviceCode},</if>
<if test="deviceId != null">device_id = #{deviceId},</if>
<if test="paramName != null">param_name = #{paramName},</if>
<if test="paramValue != null">param_value = #{paramValue},</if>
<if test="collectTime != null">collect_time = #{collectTime},</if>
<if test="recordTime != null">record_time = #{recordTime},</if>
</trim>
where record_id = #{recordId}
WHERE record_id = #{recordId}
</update>
<delete id="deleteBaseDeviceParamValByRecordId" parameterType="Long">
delete from base_device_param_val where record_id = #{recordId}
<delete id="deleteBaseDeviceParamValByRecordId" parameterType="java.lang.String">
DELETE FROM base_device_param_val WHERE record_id = #{recordId}
</delete>
<delete id="deleteBaseDeviceParamValByRecordIds" parameterType="String">
delete from base_device_param_val where record_id in
<delete id="deleteBaseDeviceParamValByRecordIds">
DELETE FROM base_device_param_val
WHERE record_id IN
<foreach item="recordId" collection="array" open="(" separator="," close=")">
#{recordId}
</foreach>
</delete>
<!-- 最新参数聚合查询每设备每参数取最新一条记录限制返回200条 -->
<!-- <select id="selectLatestBaseDeviceParamValList" parameterType="BaseDeviceParamVal" resultMap="BaseDeviceParamValResult">
SELECT * FROM (
SELECT
record_id, param_code, device_code, device_id, param_name, param_value, collect_time, record_time,
ROW_NUMBER() OVER (ORDER BY device_code, param_code) AS row_num
FROM (
SELECT
record_id, param_code, device_code, device_id, param_name, param_value, collect_time, record_time,
ROW_NUMBER() OVER (PARTITION BY device_code, param_code ORDER BY NVL(record_time, collect_time) DESC) AS rn
FROM base_device_param_val
<where>
<if test="deviceCode != null and deviceCode != ''">and device_code = #{deviceCode}</if>
<if test="paramCode != null and paramCode != ''">and param_code = #{paramCode}</if>
<if test="deviceId != null">and device_id = #{deviceId}</if>
<if test="paramName != null and paramName != ''">and param_name like '%' || #{paramName} || '%'</if>
</where>
) WHERE rn = 1
) WHERE row_num &lt;= 200
</select> -->
<select id="selectLatestBaseDeviceParamValList" parameterType="BaseDeviceParamVal" resultMap="BaseDeviceParamValResult">
SELECT *
FROM (
SELECT
record_id, param_code, device_code, device_id, param_name, param_value,
collect_time, record_time,
ROW_NUMBER() OVER (ORDER BY device_code, param_code) AS row_num
SELECT *
FROM (
SELECT record_id, param_code, device_code, device_id, param_name, param_value,
collect_time, record_time,
ROW_NUMBER() OVER (ORDER BY device_code, param_code) AS row_num
FROM (
SELECT
record_id, param_code, device_code, device_id, param_name, param_value,
collect_time, record_time,
ROW_NUMBER() OVER (PARTITION BY device_code, param_code ORDER BY NVL(record_time, collect_time) DESC) AS rn
FROM base_device_param_val B
WHERE 1=1
<if test="deviceCode != null and deviceCode != ''">AND device_code = #{deviceCode}</if>
<if test="paramCode != null and paramCode != ''">AND param_code = #{paramCode}</if>
<if test="deviceId != null">AND device_id = #{deviceId}</if>
<if test="paramName != null and paramName != ''">AND param_name LIKE '%' || #{paramName} || '%'</if>
<!-- 强烈建议增加时间窗口 -->
<if test="beginTime != null and endTime != null">
AND NVL(record_time, collect_time) BETWEEN #{beginTime} AND #{endTime}
</if>
) WHERE rn = 1
) WHERE row_num &lt;= 200
SELECT record_id, param_code, device_code, device_id, param_name, param_value,
collect_time, record_time,
ROW_NUMBER() OVER (
PARTITION BY device_code, param_code
ORDER BY NVL(record_time, collect_time) DESC
) AS rn
FROM (
<include refid="dualSourceFrom"/>
) merged_param
) latest_param
WHERE rn = 1
)
WHERE row_num &lt;= 200
</select>
<!-- 设备状态统计:基于三色灯参数获取设备运行状态统计 -->
<select id="selectDeviceStatusStatistics" resultType="java.util.Map">
WITH today_latest AS (
SELECT /*+ PARALLEL(4) */
device_code,
param_name,
ROW_NUMBER() OVER (
PARTITION BY device_code
ORDER BY NVL(record_time, collect_time) DESC,
DECODE(param_name,
'机台状态-三色灯机器报警', 1,
'机台状态-三色灯机器暂停', 2,
'机台状态-三色灯机器待机', 3,
'机台状态-三色灯机器运行', 4,
9) ASC
) AS rn
FROM base_device_param_val
WHERE param_name IN ('机台状态-三色灯机器运行', '机台状态-三色灯机器暂停', '机台状态-三色灯机器待机', '机台状态-三色灯机器报警')
AND UPPER(param_value) = 'TRUE'
AND collect_time &gt;= SYSDATE - (2/24) AND collect_time &lt; SYSDATE
<select id="selectDeviceStatusStatistics" parameterType="java.util.Map" resultType="java.util.Map">
WITH merged_param AS (
<trim suffixOverrides="UNION ALL">
SELECT device_code, param_name, collect_time, record_time
FROM BASE_DEVICE_PARAM_VAL
WHERE device_code LIKE 'OLD-%'
AND param_name IN ('机台状态-三色灯机器运行', '机台状态-三色灯机器暂停', '机台状态-三色灯机器待机', '机台状态-三色灯机器报警')
AND UPPER(param_value) = 'TRUE'
AND collect_time &gt;= SYSDATE - (2/24)
AND collect_time &lt; SYSDATE
UNION ALL
<if test="tableSuffixes != null and tableSuffixes.size() > 0">
<foreach item="suffix" collection="tableSuffixes" separator=" UNION ALL ">
SELECT device_code, param_name, collect_time, record_time
FROM BASE_DEVICE_PARAM_VAL_${suffix}
WHERE device_code NOT LIKE 'OLD-%'
AND param_name IN ('机台状态-三色灯机器运行', '机台状态-三色灯机器暂停', '机台状态-三色灯机器待机', '机台状态-三色灯机器报警')
AND UPPER(param_value) = 'TRUE'
AND collect_time &gt;= SYSDATE - (2/24)
AND collect_time &lt; SYSDATE
</foreach>
</if>
</trim>
),
today_latest AS (
SELECT device_code,
param_name,
ROW_NUMBER() OVER (
PARTITION BY device_code
ORDER BY NVL(record_time, collect_time) DESC,
DECODE(param_name,
'机台状态-三色灯机器报警', 1,
'机台状态-三色灯机器暂停', 2,
'机台状态-三色灯机器待机', 3,
'机台状态-三色灯机器运行', 4,
9) ASC
) AS rn
FROM merged_param
),
device_status AS (
SELECT device_code, param_name FROM today_latest WHERE rn = 1
SELECT device_code, param_name
FROM today_latest
WHERE rn = 1
),
status_sum AS (
SELECT
NVL(SUM(CASE WHEN param_name = '机台状态-三色灯机器运行' THEN 1 ELSE 0 END), 0) AS runningCount,
NVL(SUM(CASE WHEN param_name = '机台状态-三色灯机器暂停' THEN 1 ELSE 0 END), 0) AS stoppedCount,
NVL(SUM(CASE WHEN param_name = '机台状态-三色灯机器待机' THEN 1 ELSE 0 END), 0) AS standbyCount,
NVL(SUM(CASE WHEN param_name = '机台状态-三色灯机器报警' THEN 1 ELSE 0 END), 0) AS alarmCount
SELECT NVL(SUM(CASE WHEN param_name = '机台状态-三色灯机器运行' THEN 1 ELSE 0 END), 0) AS runningCount,
NVL(SUM(CASE WHEN param_name = '机台状态-三色灯机器暂停' THEN 1 ELSE 0 END), 0) AS stoppedCount,
NVL(SUM(CASE WHEN param_name = '机台状态-三色灯机器待机' THEN 1 ELSE 0 END), 0) AS standbyCount,
NVL(SUM(CASE WHEN param_name = '机台状态-三色灯机器报警' THEN 1 ELSE 0 END), 0) AS alarmCount
FROM device_status
),
total_cnt AS (
SELECT COUNT(1) AS totalCount FROM base_deviceledger WHERE is_flag = 1
)
SELECT
t.totalCount,
s.runningCount,
s.stoppedCount,
s.standbyCount,
s.alarmCount,
t.totalCount - s.runningCount - s.stoppedCount - s.standbyCount - s.alarmCount AS notStartedCount
SELECT t.totalCount,
s.runningCount,
s.stoppedCount,
s.standbyCount,
s.alarmCount,
t.totalCount - s.runningCount - s.stoppedCount - s.standbyCount - s.alarmCount AS notStartedCount
FROM status_sum s, total_cnt t
</select>
<!-- 获取每个设备的编号、名称、三色灯状态 -->
<select id="selectDeviceStatusList" resultType="java.util.Map">
WITH today_latest AS (
SELECT /*+ PARALLEL(4) */
device_code,
param_name,
ROW_NUMBER() OVER (PARTITION BY device_code ORDER BY NVL(record_time, collect_time) DESC) AS rn
FROM base_device_param_val
WHERE param_name IN ('机台状态-三色灯机器运行', '机台状态-三色灯机器暂停', '机台状态-三色灯机器待机','机台状态-三色灯机器报警')
AND UPPER(param_value) = 'TRUE'
AND collect_time &gt;= SYSDATE - (2/24) AND collect_time &lt; SYSDATE
<select id="selectDeviceStatusList" parameterType="java.util.Map" resultType="java.util.Map">
WITH merged_param AS (
<trim suffixOverrides="UNION ALL">
SELECT device_code, param_name, collect_time, record_time
FROM BASE_DEVICE_PARAM_VAL
WHERE device_code LIKE 'OLD-%'
AND param_name IN ('机台状态-三色灯机器运行', '机台状态-三色灯机器暂停', '机台状态-三色灯机器待机', '机台状态-三色灯机器报警')
AND UPPER(param_value) = 'TRUE'
AND collect_time &gt;= SYSDATE - (2/24)
AND collect_time &lt; SYSDATE
UNION ALL
<if test="tableSuffixes != null and tableSuffixes.size() > 0">
<foreach item="suffix" collection="tableSuffixes" separator=" UNION ALL ">
SELECT device_code, param_name, collect_time, record_time
FROM BASE_DEVICE_PARAM_VAL_${suffix}
WHERE device_code NOT LIKE 'OLD-%'
AND param_name IN ('机台状态-三色灯机器运行', '机台状态-三色灯机器暂停', '机台状态-三色灯机器待机', '机台状态-三色灯机器报警')
AND UPPER(param_value) = 'TRUE'
AND collect_time &gt;= SYSDATE - (2/24)
AND collect_time &lt; SYSDATE
</foreach>
</if>
</trim>
),
today_latest AS (
SELECT device_code,
param_name,
ROW_NUMBER() OVER (PARTITION BY device_code ORDER BY NVL(record_time, collect_time) DESC) AS rn
FROM merged_param
),
device_status AS (
SELECT device_code, param_name FROM today_latest WHERE rn = 1
SELECT device_code, param_name
FROM today_latest
WHERE rn = 1
)
SELECT
d.device_code AS deviceCode,
d.device_name AS deviceName,
d.product_line_code AS productLineCode,
CASE
WHEN s.param_name = '机台状态-三色灯机器运行' THEN '运行'
WHEN s.param_name = '机台状态-三色灯机器暂停' THEN '停机'
WHEN s.param_name = '机台状态-三色灯机器待机' THEN '待机'
WHEN s.param_name = '机台状态-三色灯机器报警' THEN '报警'
ELSE '未开机'
END AS deviceStatus,
CASE
WHEN s.param_name = '机台状态-三色灯机器运行' THEN 1
WHEN s.param_name = '机台状态-三色灯机器暂停' THEN 2
WHEN s.param_name = '机台状态-三色灯机器待机' THEN 3
WHEN s.param_name = '机台状态-三色灯机器报警' THEN 4
ELSE 0
END AS statusCode
SELECT d.device_code AS deviceCode,
d.device_name AS deviceName,
d.product_line_code AS productLineCode,
CASE
WHEN s.param_name = '机台状态-三色灯机器运行' THEN '运行'
WHEN s.param_name = '机台状态-三色灯机器暂停' THEN '停机'
WHEN s.param_name = '机台状态-三色灯机器待机' THEN '待机'
WHEN s.param_name = '机台状态-三色灯机器报警' THEN '报警'
ELSE '未开机'
END AS deviceStatus,
CASE
WHEN s.param_name = '机台状态-三色灯机器运行' THEN 1
WHEN s.param_name = '机台状态-三色灯机器暂停' THEN 2
WHEN s.param_name = '机台状态-三色灯机器待机' THEN 3
WHEN s.param_name = '机台状态-三色灯机器报警' THEN 4
ELSE 0
END AS statusCode
FROM base_deviceledger d
LEFT JOIN device_status s ON d.device_code = s.device_code
WHERE d.is_flag = 1
ORDER BY d.product_line_code, d.device_code
</select>
<!-- 获取每个设备的开机时间当天最新值 -->
<select id="selectDeviceStartTimeList" resultType="java.util.Map">
WITH today_latest AS (
SELECT /*+ PARALLEL(4) */
device_code,
param_value,
ROW_NUMBER() OVER (PARTITION BY device_code ORDER BY NVL(record_time, collect_time) DESC) AS rn
FROM base_device_param_val
WHERE param_name = '机台状态-开机时间'
AND collect_time &gt;= TRUNC(SYSDATE) AND collect_time &lt; TRUNC(SYSDATE) + 1
<select id="selectDeviceStartTimeList" parameterType="java.util.Map" resultType="java.util.Map">
WITH merged_param AS (
<trim suffixOverrides="UNION ALL">
SELECT device_code, param_value, collect_time, record_time
FROM BASE_DEVICE_PARAM_VAL
WHERE device_code LIKE 'OLD-%'
AND param_name = '机台状态-开机时间'
AND collect_time &gt;= TRUNC(SYSDATE)
AND collect_time &lt; TRUNC(SYSDATE) + 1
UNION ALL
<if test="tableSuffixes != null and tableSuffixes.size() > 0">
<foreach item="suffix" collection="tableSuffixes" separator=" UNION ALL ">
SELECT device_code, param_value, collect_time, record_time
FROM BASE_DEVICE_PARAM_VAL_${suffix}
WHERE device_code NOT LIKE 'OLD-%'
AND param_name = '机台状态-开机时间'
AND collect_time &gt;= TRUNC(SYSDATE)
AND collect_time &lt; TRUNC(SYSDATE) + 1
</foreach>
</if>
</trim>
),
today_latest AS (
SELECT device_code,
param_value,
ROW_NUMBER() OVER (PARTITION BY device_code ORDER BY NVL(record_time, collect_time) DESC) AS rn
FROM merged_param
)
SELECT
d.device_code AS deviceCode,
d.device_name AS deviceName,
d.product_line_code AS productLineCode,
NVL(t.param_value, '') AS startTime
SELECT d.device_code AS deviceCode,
d.device_name AS deviceName,
d.product_line_code AS productLineCode,
NVL(t.param_value, '') AS startTime
FROM base_deviceledger d
LEFT JOIN today_latest t ON d.device_code = t.device_code AND t.rn = 1
WHERE d.is_flag = 1
ORDER BY d.product_line_code, d.device_code
</select>
<!-- 参数追溯查询(按时间范围,必须带设备和时间条件) -->
<select id="selectTraceList" parameterType="java.util.Map" resultMap="BaseDeviceParamValResult">
SELECT * FROM (
SELECT *
FROM (
SELECT record_id, param_code, device_code, device_id, param_name, param_value,
collect_time, record_time,
ROW_NUMBER() OVER (ORDER BY collect_time DESC) AS rn
FROM base_device_param_val
WHERE device_code = #{deviceCode}
AND collect_time BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
<if test="paramCode != null and paramCode != ''">
AND param_code = #{paramCode}
</if>
) WHERE rn &lt;= 10000
FROM (
<trim suffixOverrides="UNION ALL">
SELECT <include refid="baseSelectColumns"/>
FROM BASE_DEVICE_PARAM_VAL
WHERE device_code = #{deviceCode}
AND collect_time BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
<if test="paramCode != null and paramCode != ''">
AND param_code = #{paramCode}
</if>
UNION ALL
<if test="tableSuffixes != null and tableSuffixes.size() > 0">
<foreach item="suffix" collection="tableSuffixes" separator=" UNION ALL ">
SELECT <include refid="baseSelectColumns"/>
FROM BASE_DEVICE_PARAM_VAL_${suffix}
WHERE device_code = #{deviceCode}
AND collect_time BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
<if test="paramCode != null and paramCode != ''">
AND param_code = #{paramCode}
</if>
</foreach>
</if>
</trim>
)
)
WHERE rn &lt;= 10000
ORDER BY collect_time DESC
</select>
<!-- SPC分析数据查询参数历史值限制1000条 -->
<select id="selectParamHistoryValues" parameterType="java.util.Map" resultType="java.lang.Double">
SELECT * FROM (
SELECT TO_NUMBER(param_value) AS param_value
FROM base_device_param_val
WHERE device_code = #{deviceCode}
AND param_code = #{paramCode}
AND collect_time BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
AND REGEXP_LIKE(param_value, '^-?[0-9]+\.?[0-9]*$')
SELECT *
FROM (
SELECT TO_NUMBER(param_value) AS param_value, collect_time
FROM (
<trim suffixOverrides="UNION ALL">
SELECT param_value, collect_time
FROM BASE_DEVICE_PARAM_VAL
WHERE device_code = #{deviceCode}
AND param_code = #{paramCode}
AND collect_time BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
AND REGEXP_LIKE(param_value, '^-?[0-9]+\.?[0-9]*$')
UNION ALL
<if test="tableSuffixes != null and tableSuffixes.size() > 0">
<foreach item="suffix" collection="tableSuffixes" separator=" UNION ALL ">
SELECT param_value, collect_time
FROM BASE_DEVICE_PARAM_VAL_${suffix}
WHERE device_code = #{deviceCode}
AND param_code = #{paramCode}
AND collect_time BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
AND REGEXP_LIKE(param_value, '^-?[0-9]+\.?[0-9]*$')
</foreach>
</if>
</trim>
)
ORDER BY collect_time ASC
) WHERE ROWNUM &lt;= 1000
)
WHERE ROWNUM &lt;= 1000
</select>
<!-- 查询参数名称 -->
<select id="selectParamNameByCode" parameterType="String" resultType="String">
SELECT param_name FROM (
SELECT param_name FROM base_device_param_val
WHERE param_code = #{paramCode} AND ROWNUM = 1
<select id="selectParamNameByCodeFromSources" parameterType="java.util.Map" resultType="java.lang.String">
SELECT param_name
FROM (
SELECT param_name, collect_time
FROM (
<trim suffixOverrides="UNION ALL">
SELECT param_name, collect_time
FROM BASE_DEVICE_PARAM_VAL
WHERE param_code = #{paramCode}
<if test="deviceCode != null and deviceCode != ''">
AND device_code = #{deviceCode}
</if>
<if test="startTime != null and endTime != null">
AND collect_time BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
</if>
UNION ALL
<if test="tableSuffixes != null and tableSuffixes.size() > 0">
<foreach item="suffix" collection="tableSuffixes" separator=" UNION ALL ">
SELECT param_name, collect_time
FROM BASE_DEVICE_PARAM_VAL_${suffix}
WHERE param_code = #{paramCode}
<if test="deviceCode != null and deviceCode != ''">
AND device_code = #{deviceCode}
</if>
<if test="startTime != null and endTime != null">
AND collect_time BETWEEN TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
</if>
</foreach>
</if>
</trim>
)
ORDER BY collect_time DESC
)
WHERE ROWNUM = 1
</select>
<select id="selectParamNameByCode" parameterType="java.lang.String" resultType="java.lang.String">
SELECT param_name
FROM (
SELECT param_name
FROM base_device_param_val
WHERE param_code = #{paramCode}
AND ROWNUM = 1
)
</select>
</mapper>
</mapper>

@ -58,7 +58,7 @@
<select id="selectBaseMaterialInfoList" parameterType="BaseMaterialInfo" resultMap="BaseMaterialInfoResult">
<include refid="selectBaseMaterialInfoVo"/>
<where>
<if test="materialCode != null and materialCode != ''"> and ml.material_code = #{materialCode}</if>
<if test="materialCode != null and materialCode != ''"> and ml.material_code like concat(concat('%', #{materialCode}), '%')</if>
<if test="materialName != null and materialName != ''"> and ml.material_name like concat(concat('%', #{materialName}), '%')</if>
<if test="materialCategories != null and materialCategories != ''"> and ml.material_categories = #{materialCategories}</if>
<if test="materialSubclass != null and materialSubclass != ''"> and ml.material_subclass = #{materialSubclass}</if>

@ -16,6 +16,7 @@ import com.aucma.base.service.IBaseDeviceLedgerService;
import com.aucma.base.domain.BaseDeviceParamVal;
import com.aucma.base.service.IBaseOrderInfoService;
import com.aucma.base.service.IBaseDeviceParamValService;
import com.aucma.base.support.DeviceParamTableRouter;
import com.aucma.dms.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -81,6 +82,9 @@ public class DmsMobileController extends BaseController {
@Autowired
private IBaseOrderInfoService baseOrderInfoService;
@Autowired
private DeviceParamTableRouter deviceParamTableRouter;
private static final String PARAM_CODE_PDA_CUSTOM = "9999";
private static final String PARAM_NAME_ACTUAL_RUNTIME = "机台状态-实际生产时间";
private static final String PARAM_NAME_DAILY_OUTPUT = "机台状态-实际产出数量";
@ -800,7 +804,7 @@ public class DmsMobileController extends BaseController {
int rows = dmsRecordShutDownService.updateDmsRecordShutDown(updateRecord);
// 对老设备OLD-01~OLD-05同步写入三色灯状态参数
// 对 OLD 设备同步写入三色灯状态参数
if (origin.getShutEndTime() == null && origin.getDeviceId() != null) {
// 原记录不含deviceCode需通过deviceId反查设备编号
BaseDeviceLedger deviceQuery = new BaseDeviceLedger();
@ -808,7 +812,7 @@ public class DmsMobileController extends BaseController {
List<BaseDeviceLedger> devices = baseDeviceLedgerService.selectBaseDeviceLedgerList(deviceQuery);
if (!devices.isEmpty()) {
String deviceCode = devices.get(0).getDeviceCode();
if (deviceCode != null && deviceCode.startsWith("OLD-")) {
if (deviceParamTableRouter.isOldDevice(deviceCode)) {
// 完成停机代表重新运行,三色灯置为"运行"
insertTriColorStatusParams(deviceCode, origin.getDeviceId(), true);
}
@ -828,10 +832,8 @@ public class DmsMobileController extends BaseController {
* //
*/
private void insertTriColorStatusParams(String deviceCode, Long deviceId, boolean running) {
// 仅处理 OLD-01~OLD-05
if (!"OLD-01".equals(deviceCode) && !"OLD-02".equals(deviceCode)
&& !"OLD-03".equals(deviceCode) && !"OLD-04".equals(deviceCode)
&& !"OLD-05".equals(deviceCode)) {
// 为什么这样做OLD 设备识别规则必须全系统统一,否则新增 OLD 编码后会出现状态丢失。
if (!deviceParamTableRouter.isOldDevice(deviceCode)) {
return;
}

@ -4,6 +4,7 @@ import com.aucma.base.domain.BaseDeviceLedger;
import com.aucma.base.domain.BaseDeviceParamVal;
import com.aucma.base.mapper.BaseDeviceLedgerMapper;
import com.aucma.base.mapper.BaseDeviceParamValMapper;
import com.aucma.base.service.IBaseDeviceParamValService;
import com.aucma.common.constant.AnDonConstants;
import com.aucma.common.utils.DateUtils;
import com.aucma.common.utils.StringUtils;
@ -38,6 +39,9 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService {
@Autowired
private BaseDeviceParamValMapper baseDeviceParamValMapper;
@Autowired
private IBaseDeviceParamValService baseDeviceParamValService;
@Autowired
private ProductPlanInfoMapper productPlanInfoMapper;
@ -63,8 +67,8 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService {
public AndonDashboardDTO.DeviceStatusSummary getDeviceStatusSummary(String productLineCode) {
AndonDashboardDTO.DeviceStatusSummary summary = new AndonDashboardDTO.DeviceStatusSummary();
// 直接调用BaseDeviceParamValMapper获取真实设备状态统计
Map<String, Object> stats = baseDeviceParamValMapper.selectDeviceStatusStatistics();
// 为什么这样做:分表后状态查询依赖 tableSuffixes 路由,统一走 base 服务才能避免各调用方重复拼装参数。
Map<String, Object> stats = baseDeviceParamValService.selectDeviceStatusStatistics();
if (stats == null || stats.isEmpty()) {
summary.setTotalDevices(0);
@ -77,19 +81,21 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService {
}
// 设置统计数据
Number totalCount = (Number) stats.get("totalCount");
Number runningCount = (Number) stats.get("runningCount");
Number stoppedCount = (Number) stats.get("stoppedCount");
Number standbyCount = (Number) stats.get("standbyCount");
// 为什么这样做:不同 JDBC/MyBatis 映射下聚合别名可能保留原样,也可能被转成大写,这里同时兼容两种结果键。
Number totalCount = getNumber(stats, "TOTALCOUNT", "totalCount");
Number runningCount = getNumber(stats, "RUNNINGCOUNT", "runningCount");
Number stoppedCount = getNumber(stats, "STOPPEDCOUNT", "stoppedCount");
Number standbyCount = getNumber(stats, "STANDBYCOUNT", "standbyCount");
Number alarmCount = getNumber(stats, "ALARMCOUNT", "alarmCount");
summary.setTotalDevices(totalCount != null ? totalCount.intValue() : 0);
summary.setRunningDevices(runningCount != null ? runningCount.intValue() : 0);
summary.setStoppedDevices(stoppedCount != null ? stoppedCount.intValue() : 0);
summary.setIdleDevices(standbyCount != null ? standbyCount.intValue() : 0);
summary.setFaultDevices(0); // 三色灯没有故障状态,使用报警代替
summary.setFaultDevices(alarmCount != null ? alarmCount.intValue() : 0);
// 获取设备状态详情
List<Map<String, Object>> deviceStatusList = baseDeviceParamValMapper.selectDeviceStatusList();
List<Map<String, Object>> deviceStatusList = baseDeviceParamValService.selectDeviceStatusList();
List<AndonDashboardDTO.DeviceStatusDetail> details = new ArrayList<>();
if (deviceStatusList != null) {
@ -581,4 +587,12 @@ public class AndonDashboardServiceImpl implements IAndonDashboardService {
.setScale(places, RoundingMode.HALF_UP)
.doubleValue();
}
private Number getNumber(Map<String, Object> data, String upperKey, String lowerKey) {
Object value = data.get(upperKey);
if (value == null) {
value = data.get(lowerKey);
}
return value instanceof Number ? (Number) value : null;
}
}

@ -1,5 +1,6 @@
package com.aucma.report.service.impl;
import com.aucma.base.service.IBaseDeviceParamValService;
import com.aucma.report.domain.vo.*;
import com.aucma.report.mapper.Board4Mapper;
import com.aucma.report.service.IBoard4Service;
@ -22,6 +23,9 @@ public class Board4ServiceImpl implements IBoard4Service {
@Autowired
private Board4Mapper board4Mapper;
@Autowired
private IBaseDeviceParamValService baseDeviceParamValService;
/**
*
* 11123112
@ -93,20 +97,20 @@ public class Board4ServiceImpl implements IBoard4Service {
/**
*
* DEVICE_STATUS
* aucma-base
*/
@Override
public Board4DeviceStatusVo getDeviceStatus() {
// 初始化返回对象
Board4DeviceStatusVo vo = new Board4DeviceStatusVo();
// 查询设备状态分布
HashMap<String, Object> stats = board4Mapper.selectDeviceStatusStatistics();
// Whyboard4 与 board1 必须复用同一套双源状态口径,否则页面展示会出现数量不一致。
HashMap<String, Object> stats = new HashMap<>(baseDeviceParamValService.selectDeviceStatusStatistics());
if (stats != null) {
// 正常/告警/停机/总数
vo.setNormalCount(getLongValue(stats.get("NORMAL_COUNT")));
vo.setAlarmCount(getLongValue(stats.get("ALARM_COUNT")));
vo.setStopCount(getLongValue(stats.get("STOP_COUNT")));
vo.setTotalCount(getLongValue(stats.get("TOTAL_COUNT")));
// 正常=运行台数board4 页面文案沿用“正常”
vo.setNormalCount(getLongValue(stats.get("RUNNINGCOUNT")));
vo.setAlarmCount(getLongValue(stats.get("ALARMCOUNT")));
vo.setStopCount(getLongValue(stats.get("STOPPEDCOUNT")));
vo.setTotalCount(getLongValue(stats.get("TOTALCOUNT")));
} else {
// 无数据时默认0
vo.setNormalCount(0L);

@ -11,84 +11,38 @@
WHERE TO_CHAR(BEGIN_DATE, 'YYYY') = TO_CHAR(ADD_MONTHS(SYSDATE, -12), 'YYYY')
</select>
<!-- 查询月累计产量本自然月当月1日至月末 -->
<!-- 新逻辑:与日累计一致,按设备参数表取每台设备本月最新的“机台状态-实际产出数量”汇总 -->
<!-- 原工单累计逻辑保留注释:
SELECT NVL(SUM(COMPLETE_AMOUNT), 0)
FROM BASE_ORDERINFO
WHERE TO_CHAR(BEGIN_DATE, 'YYYY-MM') = TO_CHAR(SYSDATE, 'YYYY-MM')
-->
<!-- <select id="selectMonthProductionTotal" resultType="java.lang.Long">
/* 按设备取本月窗口内的最早值与最新值差值再汇总无起始值则按0计算 */
SELECT NVL(SUM(latest_val - earliest_val), 0)
FROM (
SELECT device_code,
NVL(MAX(CASE WHEN rn_desc = 1 THEN val END), 0) AS latest_val,
NVL(MAX(CASE WHEN rn_asc = 1 THEN val END), 0) AS earliest_val
FROM (
SELECT DEVICE_CODE,
TO_NUMBER(PARAM_VALUE) AS val,
ROW_NUMBER() OVER (PARTITION BY DEVICE_CODE ORDER BY COLLECT_TIME DESC) AS rn_desc,
ROW_NUMBER() OVER (PARTITION BY DEVICE_CODE ORDER BY COLLECT_TIME ASC) AS rn_asc
FROM BASE_DEVICE_PARAM_VAL
WHERE PARAM_NAME = '机台状态-实际产出数量'
AND COLLECT_TIME &gt;= TRUNC(SYSDATE, 'MM')
AND COLLECT_TIME &lt; ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1)
)
GROUP BY device_code
)
</select> -->
<select id="selectMonthProductionTotal" resultType="java.lang.Long">
/* 按天取“生产计数-当前日期生产总数”每台设备当日最新值,再汇总本月所有天 */
SELECT NVL(SUM(daily_val), 0)
FROM (
SELECT TRUNC(COLLECT_TIME) AS collect_day,
DEVICE_CODE,
MAX(TO_NUMBER(PARAM_VALUE)) KEEP (DENSE_RANK LAST ORDER BY COLLECT_TIME) AS daily_val
FROM BASE_DEVICE_PARAM_VAL
WHERE PARAM_NAME = '生产计数-当前日期生产总数'
AND COLLECT_TIME &gt;= TRUNC(SYSDATE, 'MM')
AND COLLECT_TIME &lt; ADD_MONTHS(TRUNC(SYSDATE, 'MM'), 1)
GROUP BY TRUNC(COLLECT_TIME), DEVICE_CODE
)
SELECT
NVL((
SELECT SUM(d.daily_prod)
FROM DEVICE_DAILY_PRODUCTION d
WHERE d.prod_date &gt;= TRUNC(SYSDATE, 'MM')
AND d.prod_date &lt; TRUNC(SYSDATE) + 1
AND d.param_name = '机台状态-实际产出数量'
), 0)
+
NVL((
SELECT SUM(r.current_total)
FROM RT_DAILY_PROD_STATE r
WHERE r.prod_date &gt;= TRUNC(SYSDATE, 'MM')
AND r.prod_date &lt; TRUNC(SYSDATE) + 1
AND r.param_name = '机台状态-实际产出数量'
AND NOT EXISTS (
SELECT 1
FROM DEVICE_DAILY_PRODUCTION d
WHERE d.prod_date = r.prod_date
AND d.device_code = r.device_code
AND d.param_name = r.param_name
)
), 0)
FROM dual
</select>
<!-- 查询日累计产量当天00:00-23:59 工艺参数) -->
<!-- 使用BASE_DEVICE_PARAM_VAL表通过PARAM_NAME='机台状态-实际产出数量'定位参数 -->
<!-- 注意PARAM_CODE可能因设备不同而变化但PARAM_NAME是固定的 -->
<!-- 取每台设备当天最新的一条记录的实际产出数量进行汇总 -->
<!-- <select id="selectDayProductionTotal" resultType="java.lang.Long">
/* 按设备取当天窗口内的最早值与最新值差值再汇总无起始值则按0计算 */
SELECT NVL(SUM(latest_val - earliest_val), 0)
FROM (
SELECT device_code,
NVL(MAX(CASE WHEN rn_desc = 1 THEN val END), 0) AS latest_val,
NVL(MAX(CASE WHEN rn_asc = 1 THEN val END), 0) AS earliest_val
FROM (
SELECT DEVICE_CODE,
TO_NUMBER(PARAM_VALUE) AS val,
ROW_NUMBER() OVER (PARTITION BY DEVICE_CODE ORDER BY COLLECT_TIME DESC) AS rn_desc,
ROW_NUMBER() OVER (PARTITION BY DEVICE_CODE ORDER BY COLLECT_TIME ASC) AS rn_asc
FROM BASE_DEVICE_PARAM_VAL
WHERE PARAM_NAME = '机台状态-实际产出数量'
AND COLLECT_TIME &gt;= TRUNC(SYSDATE)
AND COLLECT_TIME &lt; TRUNC(SYSDATE) + 1
)
GROUP BY device_code
)
</select> -->
<select id="selectDayProductionTotal" resultType="java.lang.Long">
/* 取当天每台设备“生产计数-当前日期生产总数”的最新值再汇总 */
SELECT NVL(SUM(daily_val), 0)
FROM (
SELECT DEVICE_CODE,
MAX(TO_NUMBER(PARAM_VALUE)) KEEP (DENSE_RANK LAST ORDER BY COLLECT_TIME) AS daily_val
FROM BASE_DEVICE_PARAM_VAL
WHERE PARAM_NAME = '生产计数-当前日期生产总数'
AND COLLECT_TIME &gt;= TRUNC(SYSDATE)
AND COLLECT_TIME &lt; TRUNC(SYSDATE) + 1
GROUP BY DEVICE_CODE
)
SELECT NVL(SUM(current_total), 0)
FROM RT_DAILY_PROD_STATE
WHERE prod_date = TRUNC(SYSDATE)
AND param_name = '机台状态-实际产出数量'
</select>
<!-- 查询本周工单统计计划数、完成数周一00:00 - 周日23:59 -->
@ -115,15 +69,14 @@
</select>
<!-- 查询设备状态统计 -->
<!-- DEVICE_STATUS: NUMBER(1,0)类型0=使用/正常, 1=停用/告警, 2=报废/停机 -->
<!-- IS_FLAG: NUMBER(1,0)类型0=有效 -->
<!-- 仅保留兼容用途board4 实际状态统计应复用 aucma-base 的双源三色灯查询 -->
<select id="selectDeviceStatusStatistics" resultType="java.util.HashMap">
SELECT COUNT(*) AS TOTAL_COUNT,
SUM(CASE WHEN DEVICE_STATUS = 0 THEN 1 ELSE 0 END) AS NORMAL_COUNT,
SUM(CASE WHEN DEVICE_STATUS = 1 THEN 1 ELSE 0 END) AS ALARM_COUNT,
SUM(CASE WHEN DEVICE_STATUS = 2 THEN 1 ELSE 0 END) AS STOP_COUNT
FROM BASE_DEVICELEDGER
WHERE IS_FLAG = 0
WHERE IS_FLAG = 1
</select>
<!-- 查询总维修次数 -->
@ -197,25 +150,15 @@
) WHERE ROWNUM &lt;= 10
</select>
<!-- 查询设备分析列表(各设备机台实际产量) -->
<!-- 从BASE_DEVICE_PARAM_VAL获取当天每台设备的最新实际产出数量 -->
<!-- 注意通过PARAM_NAME='机台状态-实际产出数量'定位参数而非PARAM_CODE -->
<!-- 因为PARAM_CODE可能因设备不同而变化但PARAM_NAME是固定的 -->
<!-- 查询设备分析列表(各设备今日增量产量) -->
<select id="selectDeviceProductionAnalysis" resultType="com.aucma.report.domain.vo.Board4DeviceProductionVo">
SELECT d.DEVICE_NAME AS deviceName,
NVL(TO_NUMBER(p.PARAM_VALUE), 0) AS production
NVL(r.current_total, 0) AS production
FROM BASE_DEVICELEDGER d
LEFT JOIN (
SELECT DEVICE_CODE, PARAM_VALUE
FROM (
SELECT DEVICE_CODE, PARAM_VALUE,
ROW_NUMBER() OVER (PARTITION BY DEVICE_CODE ORDER BY COLLECT_TIME DESC) AS RN
FROM BASE_DEVICE_PARAM_VAL
WHERE PARAM_NAME = '机台状态-实际产出数量'
AND COLLECT_TIME &gt;= TRUNC(SYSDATE) AND COLLECT_TIME &lt; TRUNC(SYSDATE) + 1
)
WHERE RN = 1
) p ON d.DEVICE_CODE = p.DEVICE_CODE
LEFT JOIN RT_DAILY_PROD_STATE r
ON d.DEVICE_CODE = r.DEVICE_CODE
AND r.prod_date = TRUNC(SYSDATE)
AND r.param_name = '机台状态-实际产出数量'
WHERE d.IS_FLAG = 1
ORDER BY production DESC
</select>

Loading…
Cancel
Save