package com.ruoyi.home.controller;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.ruoyi.approve.pojo.ApproveProcess;
|
import com.ruoyi.device.mapper.DeviceLedgerMapper;
|
import com.ruoyi.device.mapper.DeviceRepairMapper;
|
import com.ruoyi.device.pojo.DeviceRepair;
|
import com.ruoyi.dto.MapDto;
|
import com.ruoyi.framework.aspectj.lang.annotation.Log;
|
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
|
import com.ruoyi.framework.web.controller.BaseController;
|
import com.ruoyi.framework.web.domain.R;
|
import com.ruoyi.home.annotation.DefaultType;
|
import com.ruoyi.home.dto.*;
|
import com.ruoyi.home.service.HomeService;
|
import com.ruoyi.production.mapper.ProductionOrderMapper;
|
import com.ruoyi.production.mapper.ProductionProductOutputMapper;
|
import com.ruoyi.production.pojo.ProductionOrder;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.Operation;
|
import lombok.AllArgsConstructor;
|
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RestController;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.text.ParseException;
|
import java.time.LocalDate;
|
import java.time.ZoneId;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Objects;
|
|
/**
|
* @author :yys
|
* @date : 2025/7/25 9:15
|
*/
|
@RestController
|
@Tag(name = "首页统计")
|
@RequestMapping("/home")
|
@AllArgsConstructor
|
public class HomeController extends BaseController {
|
|
private final HomeService homeService;
|
private final ProductionOrderMapper productionOrderMapper;
|
private final ProductionProductOutputMapper productionProductOutputMapper;
|
private final DeviceLedgerMapper deviceLedgerMapper;
|
private final DeviceRepairMapper deviceRepairMapper;
|
|
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
private static final Integer ORDER_STATUS_WAIT = 1;
|
private static final Integer ORDER_STATUS_RUNNING = 2;
|
private static final Integer ORDER_STATUS_COMPLETED = 3;
|
private static final Integer ORDER_STATUS_PAUSED = 4;
|
|
/********************************************************基础类*****************************************************/
|
@GetMapping("/todos")
|
@Log(title = "待办事项", businessType = BusinessType.OTHER)
|
@Operation(summary = "待办事项")
|
public R todos(ApproveProcess req) throws ParseException {
|
List<ApproveProcess> approveProcessList = homeService.todos();
|
return R.ok(approveProcessList);
|
}
|
|
@GetMapping("/approveAndDeviceTodos")
|
@Operation(summary = "审批协同,设备报修待办事项")
|
public R approveAndDeviceTodos(){
|
Map<String, Object> map = homeService.approveAndDeviceTodos();
|
return R.ok(map);
|
}
|
|
@GetMapping("/noticesCount")
|
@Operation(summary = "未过期的公告数量")
|
public R noticesCount(){
|
Long count = homeService.noticesCount();
|
return R.ok(count);
|
}
|
|
@GetMapping("/deptStaffDistribution")
|
@Operation(summary = "各部门人员分布")
|
public R deptStaffDistribution() {
|
DeptStaffDistributionDto dto = homeService.deptStaffDistribution();
|
return R.ok(dto);
|
}
|
|
@GetMapping("/summaryStatistics")
|
@Operation(summary = "员工-客户-供应商总数")
|
public R summaryStatistics() {
|
HomeSummaryDto homeSummaryDto = homeService.summaryStatistics();
|
return R.ok(homeSummaryDto);
|
}
|
|
/********************************************************营销采购类**************************************************/
|
@GetMapping("/supplierPurchaseRanking")
|
@Operation(summary = "供应商采购排名")
|
public R supplierPurchaseRanking(@DefaultType Integer type) {
|
List<SupplierPurchaseRankingDto> list = homeService.supplierPurchaseRanking(type);
|
return R.ok(list);
|
}
|
|
@GetMapping("/customerRevenueAnalysis")
|
@Operation(summary = "客户营收贡献数值分析")
|
public R customerRevenueAnalysis(Long customerId, @DefaultType Integer type) {
|
CustomerRevenueAnalysisDto dto = homeService.customerRevenueAnalysis(customerId, type);
|
return R.ok(dto);
|
}
|
|
@GetMapping("/customerContributionRanking")
|
@Operation(summary = "客户金额贡献排名")
|
public R customerContributionRanking(@DefaultType Integer type) {
|
List<CustomerContributionRankingDto> list = homeService.customerContributionRanking(type);
|
return R.ok(list);
|
}
|
|
@GetMapping("/productSalesAnalysis")
|
@Operation(summary = "各产品销售金额分析")
|
public R productSalesAnalysis() {
|
List<MapDto> list = homeService.productSalesAnalysis();
|
return R.ok(list);
|
}
|
|
@GetMapping("/rawMaterialPurchaseAmountRatio")
|
@Operation(summary = "原材料采购金额占比")
|
public R rawMaterialPurchaseAmountRatio(){
|
List<MapDto> list = homeService.rawMaterialPurchaseAmountRatio();
|
return R.ok(list);
|
}
|
|
@GetMapping("/business")
|
@Log(title = "销售-采购-库存数据", businessType = BusinessType.OTHER)
|
@Operation(summary = "销售-采购-库存数据")
|
public R business(HomeBusinessDto req) {
|
HomeBusinessDto homeBusinessDto = homeService.business();
|
return R.ok(homeBusinessDto);
|
}
|
|
@GetMapping("/analysisCustomerContractAmounts")
|
@Log(title = "客户合同金额分析", businessType = BusinessType.OTHER)
|
@Operation(summary = "客户合同金额分析")
|
public R analysisCustomerContractAmounts(AnalysisCustomerContractAmountsDto req) {
|
AnalysisCustomerContractAmountsDto analysisCustomerContractAmounts = homeService.analysisCustomerContractAmounts();
|
return R.ok(analysisCustomerContractAmounts);
|
}
|
|
/********************************************************生产类*****************************************************/
|
@GetMapping("/inputOutputAnalysis")
|
@Operation(summary = "投入产出分析")
|
public R inputOutputAnalysis(@DefaultType Integer type){
|
List<InputOutputAnalysisDto> list = homeService.inputOutputAnalysis(type);
|
return R.ok(list);
|
}
|
|
@GetMapping("/processOutputAnalysis")
|
@Operation(summary = "工序产出分析")
|
public R processOutputAnalysis(@DefaultType Integer type){
|
List<MapDto> list = homeService.processOutputAnalysis(type);
|
return R.ok(list);
|
}
|
|
@GetMapping("/workOrderEfficiencyAnalysis")
|
@Operation(summary = "工单执行效率分析")
|
public R workOrderEfficiencyAnalysis(@DefaultType Integer type){
|
List<WorkOrderEfficiencyDto> list = homeService.workOrderEfficiencyAnalysis(type);
|
return R.ok(list);
|
}
|
|
@GetMapping("/productionAccountingAnalysis")
|
@Operation(summary = "生产核算分析")
|
public R productionAccountingAnalysis(@DefaultType Integer type){
|
List<ProductionAccountingDto> list = homeService.productionAccountingAnalysis(type);
|
return R.ok(list);
|
}
|
|
@GetMapping("/orderCount")
|
@Operation(summary = "订单数")
|
public R orderCount(){
|
return R.ok(homeService.orderCount());
|
}
|
|
@GetMapping("/progressStatistics")
|
@Operation(summary = "各生产订单的完成进度统计")
|
public R progressStatistics(){
|
ProductionProgressDto productionProgressDto = homeService.productionProgress();
|
return R.ok(productionProgressDto);
|
}
|
|
@GetMapping("/workInProcessTurnover")
|
@Operation(summary = "在制品周转情况")
|
public R workInProcessTurnover(){
|
ProductionTurnoverDto productionTurnoverDto = homeService.workInProcessTurnover();
|
return R.ok(productionTurnoverDto);
|
}
|
|
@GetMapping("/processDataProductionStatistics")
|
@Operation(summary = "工序数据生产统计数据")
|
public R processDataProductionStatistics(@DefaultType Integer type,@RequestParam(required = false) List<Long> processIds) {
|
List<processDataProductionStatisticsDto> list = homeService.processDataProductionStatistics(type, processIds);
|
return R.ok(list);
|
}
|
|
/********************************************************质量类*****************************************************/
|
@GetMapping("/productionOverview")
|
@Operation(summary = "Production Overview")
|
public R productionOverview() {
|
LocalDate today = LocalDate.now();
|
Map<String, BigDecimal> totalStats = loadOutputStats(LocalDate.of(2000, 1, 1), today.plusDays(1));
|
BigDecimal totalOutput = totalStats.get("quantity");
|
BigDecimal totalScrap = totalStats.get("scrapQty");
|
BigDecimal yieldRate = calcRate(totalOutput, totalOutput.add(totalScrap));
|
|
Map<String, Object> result = new LinkedHashMap<>();
|
result.put("totalOutput", scale(totalOutput));
|
result.put("totalScrap", scale(totalScrap));
|
result.put("yieldRate", scale(yieldRate));
|
return R.ok(result);
|
}
|
|
@GetMapping("/productionRealtimeBoard")
|
@Operation(summary = "Production Realtime Board")
|
public R productionRealtimeBoard() {
|
LocalDate today = LocalDate.now();
|
LocalDate yesterday = today.minusDays(1);
|
|
BigDecimal todayDeviceOee = calcDeviceOee(today);
|
BigDecimal yesterdayDeviceOee = calcDeviceOee(yesterday);
|
|
BigDecimal todayOrderAchievementRate = calcOrderAchievementRate(today);
|
BigDecimal yesterdayOrderAchievementRate = calcOrderAchievementRate(yesterday);
|
|
BigDecimal todayDefectRate = calcDefectRate(today);
|
BigDecimal yesterdayDefectRate = calcDefectRate(yesterday);
|
|
Map<String, Object> result = new LinkedHashMap<>();
|
result.put("deviceOee", buildRealtimeMetric(todayDeviceOee, todayDeviceOee.subtract(yesterdayDeviceOee)));
|
result.put("orderAchievementRate", buildRealtimeMetric(todayOrderAchievementRate, todayOrderAchievementRate.subtract(yesterdayOrderAchievementRate)));
|
result.put("defectRate", buildRealtimeMetric(todayDefectRate, todayDefectRate.subtract(yesterdayDefectRate)));
|
return R.ok(result);
|
}
|
|
@GetMapping("/productionOrderProgress")
|
@Operation(summary = "Production Order Progress")
|
public R productionOrderProgress(@RequestParam(defaultValue = "all") String tab,
|
@RequestParam(defaultValue = "1") Long pageNum,
|
@RequestParam(defaultValue = "10") Long pageSize) {
|
long safePageNum = pageNum == null || pageNum < 1 ? 1 : pageNum;
|
long safePageSize = pageSize == null || pageSize < 1 ? 10 : Math.min(pageSize, 50);
|
Integer status = resolveOrderStatus(tab);
|
long offset = (safePageNum - 1) * safePageSize;
|
List<Map<String, Object>> rawRows = productionOrderMapper.selectHomeOrderProgressPage(status, offset, safePageSize);
|
List<Map<String, Object>> records = new ArrayList<>();
|
if (rawRows != null) {
|
for (Map<String, Object> rawRow : rawRows) {
|
records.add(buildOrderProgressRow(rawRow));
|
}
|
}
|
|
long inProgressCount = 0L;
|
long completedCount = 0L;
|
long pausedCount = 0L;
|
List<Map<String, Object>> statusCountRows = productionOrderMapper.countHomeOrderProgressByStatus();
|
if (statusCountRows != null) {
|
for (Map<String, Object> countRow : statusCountRows) {
|
Integer statusKey = toInteger(countRow.get("status"));
|
long cnt = toLong(countRow.get("cnt"));
|
if (Objects.equals(statusKey, ORDER_STATUS_RUNNING)) {
|
inProgressCount = cnt;
|
} else if (Objects.equals(statusKey, ORDER_STATUS_COMPLETED)) {
|
completedCount = cnt;
|
} else if (Objects.equals(statusKey, ORDER_STATUS_PAUSED)) {
|
pausedCount = cnt;
|
}
|
}
|
}
|
|
Map<String, Object> result = new LinkedHashMap<>();
|
result.put("tab", tab);
|
result.put("total", toLong(productionOrderMapper.countHomeOrderProgress(status)));
|
result.put("pageNum", safePageNum);
|
result.put("pageSize", safePageSize);
|
result.put("inProgressCount", inProgressCount);
|
result.put("completedCount", completedCount);
|
result.put("pausedCount", pausedCount);
|
result.put("records", records);
|
return R.ok(result);
|
}
|
|
@GetMapping("/todayProductionPlan")
|
@Operation(summary = "Today Production Plan")
|
public R todayProductionPlan(@RequestParam(defaultValue = "4") Long limit) {
|
long safeLimit = limit == null || limit < 1 ? 4 : Math.min(limit, 20);
|
List<Map<String, Object>> records = new ArrayList<>();
|
List<Map<String, Object>> rawRows = productionOrderMapper.selectHomeTodayProductionPlan(safeLimit);
|
if (rawRows != null) {
|
for (Map<String, Object> rawRow : rawRows) {
|
Map<String, Object> row = new LinkedHashMap<>();
|
Integer rowStatus = toInteger(rawRow.get("status"));
|
row.put("orderNo", rawRow.get("orderNo"));
|
row.put("productName", rawRow.get("productName"));
|
row.put("plannedQuantity", scale(toBigDecimal(rawRow.get("plannedQuantity"))));
|
row.put("dueDate", rawRow.get("dueDate"));
|
row.put("status", rowStatus);
|
row.put("statusLabel", mapOrderStatusLabel(rowStatus));
|
records.add(row);
|
}
|
}
|
|
Map<String, Object> result = new LinkedHashMap<>();
|
result.put("total", toLong(productionOrderMapper.countHomeTodayProductionPlan()));
|
result.put("records", records);
|
return R.ok(result);
|
}
|
|
@GetMapping("/rawMaterialDetection")
|
@Operation(summary = "原材料检测")
|
public R rawMaterialDetection(@DefaultType Integer type){
|
return R.ok(homeService.rawMaterialDetection(type));
|
}
|
|
@GetMapping("/processDetection")
|
@Operation(summary = "过程检测")
|
public R processDetection(@DefaultType Integer type){
|
return R.ok(homeService.processDetection(type));
|
}
|
|
@GetMapping("/factoryDetection")
|
@Operation(summary = "成品出厂检测")
|
public R factoryDetection(@DefaultType Integer type){
|
return R.ok(homeService.factoryDetection(type));
|
}
|
|
@GetMapping("/qualityInspectionCount")
|
@Operation(summary = "质量检验数量")
|
public R qualityInspectionCount(){
|
QualityInspectionCountDto qualityInspectionCountDto = homeService.qualityInspectionCount();
|
return R.ok(qualityInspectionCountDto);
|
}
|
|
@GetMapping("/nonComplianceWarning")
|
@Operation(summary = "不合格预警")
|
public R nonComplianceWarning(){
|
NonComplianceWarningDto nonComplianceWarningDto = homeService.nonComplianceWarning();
|
return R.ok(nonComplianceWarningDto);
|
}
|
|
@GetMapping("/completedInspectionCount")
|
@Operation(summary = "完成检验数")
|
public R completedInspectionCount(){
|
List<CompletedInspectionCountDto> list = homeService.completedInspectionCount();
|
return R.ok(list);
|
}
|
|
@GetMapping("/unqualifiedProductRanking")
|
@Operation(summary = "不合格产品排名")
|
public R unqualifiedProductRanking(){
|
List<UnqualifiedProductRankDto> list = homeService.unqualifiedProductRanking();
|
return R.ok(list);
|
}
|
|
@GetMapping("/unqualifiedProductProcessingAnalysis")
|
@Operation(summary = "不合格检品处理分析")
|
public R unqualifiedProductProcessingAnalysis(){
|
List<MapDto> list = homeService.unqualifiedProductProcessingAnalysis();
|
return R.ok(list);
|
}
|
|
@GetMapping("/qualityStatistics")
|
@Log(title = "质量分析", businessType = BusinessType.OTHER)
|
@Operation(summary = "质量分析")
|
public R qualityStatistics(QualityStatisticsDto req) {
|
QualityStatisticsDto qualityStatisticsDto = homeService.qualityStatistics();
|
return R.ok(qualityStatisticsDto);
|
}
|
|
@GetMapping("/qualityInspectionStatistics")
|
@Operation(summary = "质量统计")
|
public R qualityInspectionStatistics(@DefaultType Integer type) {
|
QualityStatisticsDto dto = homeService.qualityInspectionStatistics(type);
|
return R.ok(dto);
|
}
|
|
/********************************************************财务类*****************************************************/
|
@GetMapping("/incomeExpenseAnalysis")
|
@Operation(summary = "支收对比分析")
|
public R incomeExpenseAnalysis(@DefaultType Integer type) {
|
List<Map<String, Object>> result = homeService.incomeExpenseAnalysis(type);
|
return R.ok(result);
|
}
|
|
@GetMapping("/profitTrendAnalysis")
|
@Operation(summary = "利润趋势分析")
|
public R profitTrendAnalysis(){
|
List<MapDto> list = homeService.profitTrendAnalysis();
|
return R.ok(list);
|
}
|
|
@GetMapping("/expenseCompositionAnalysis")
|
@Operation(summary = "构成分析")
|
public R expenseCompositionAnalysis(@DefaultType Integer type) {
|
List<MapDto> list = homeService.expenseCompositionAnalysis(type);
|
return R.ok(list);
|
}
|
|
@GetMapping("/monthlyIncome")
|
@Operation(summary = "月度收入")
|
public R monthlyIncome(){
|
MonthlyIncomeDto dto = homeService.monthlyIncome();
|
return R.ok(dto);
|
}
|
|
@GetMapping("/monthlyExpenditure")
|
@Operation(summary = "月度支出")
|
public R monthlyExpenditure(){
|
MonthlyExpenditureDto dto = homeService.monthlyExpenditure();
|
return R.ok(dto);
|
}
|
|
@GetMapping("/statisticsReceivablePayable")
|
@Log(title = "应收应付统计", businessType = BusinessType.OTHER)
|
@Operation(summary = "应收应付统计")
|
public R statisticsReceivablePayable(StatisticsReceivablePayableDto req, @DefaultType Integer type ) {
|
StatisticsReceivablePayableDto statisticsReceivablePayable = homeService.statisticsReceivablePayable(type);
|
return R.ok(statisticsReceivablePayable);
|
}
|
|
/********************************************************仓储类*****************************************************/
|
|
@GetMapping("/productCategoryDistribution")
|
@Operation(summary = "产品大类分布")
|
public R productCategoryDistribution() {
|
ProductCategoryDistributionDto dto = homeService.productCategoryDistribution();
|
return R.ok(dto);
|
}
|
|
@GetMapping("/salesPurchaseStorageProductCount")
|
@Operation(summary = "销售-采购-储存产品数")
|
public R salesPurchaseStorageProductCount(){
|
List<MapDto> list = homeService.salesPurchaseStorageProductCount();
|
return R.ok(list);
|
}
|
|
@GetMapping("/productInOutAnalysis")
|
@Operation(summary = "产品出入库分析")
|
public R productInOutAnalysis(@DefaultType Integer type){
|
List<Map<String, Object>> result = homeService.productInOutAnalysis(type);
|
return R.ok(result);
|
}
|
|
@GetMapping("/productTurnoverDays")
|
@Operation(summary = "产品周转天数")
|
public R productTurnoverDays(){
|
List<MapDto> list = homeService.productTurnoverDays();
|
return R.ok(list);
|
}
|
|
private Map<String, Object> buildOrderProgressRow(Map<String, Object> rawRow) {
|
Map<String, Object> row = new LinkedHashMap<>();
|
Integer rowStatus = toInteger(rawRow.get("status"));
|
row.put("orderNo", rawRow.get("orderNo"));
|
row.put("productName", rawRow.get("productName"));
|
row.put("plannedQuantity", scale(toBigDecimal(rawRow.get("plannedQuantity"))));
|
row.put("completedQuantity", scale(toBigDecimal(rawRow.get("completedQuantity"))));
|
row.put("completionRate", scale(toBigDecimal(rawRow.get("completionRate"))));
|
row.put("dueDate", rawRow.get("dueDate"));
|
row.put("status", rowStatus);
|
row.put("statusLabel", mapOrderStatusLabel(rowStatus));
|
return row;
|
}
|
|
private Integer resolveOrderStatus(String tab) {
|
if (tab == null) {
|
return null;
|
}
|
String normalized = tab.trim().toLowerCase();
|
if ("inprogress".equals(normalized)) {
|
return ORDER_STATUS_RUNNING;
|
}
|
if ("completed".equals(normalized)) {
|
return ORDER_STATUS_COMPLETED;
|
}
|
if ("paused".equals(normalized)) {
|
return ORDER_STATUS_PAUSED;
|
}
|
return null;
|
}
|
|
private String mapOrderStatusLabel(Integer status) {
|
if (Objects.equals(status, ORDER_STATUS_WAIT)) {
|
return "待开始";
|
}
|
if (Objects.equals(status, ORDER_STATUS_RUNNING)) {
|
return "进行中";
|
}
|
if (Objects.equals(status, ORDER_STATUS_COMPLETED)) {
|
return "已完成";
|
}
|
if (Objects.equals(status, ORDER_STATUS_PAUSED)) {
|
return "已暂停";
|
}
|
return "未知";
|
}
|
|
private Map<String, BigDecimal> loadOutputStats(LocalDate startDate, LocalDate endDateExclusive) {
|
String start = startDate.atStartOfDay().format(DATE_TIME_FORMATTER);
|
String end = endDateExclusive.atStartOfDay().format(DATE_TIME_FORMATTER);
|
|
BigDecimal quantity = BigDecimal.ZERO;
|
BigDecimal scrapQty = BigDecimal.ZERO;
|
List<Map<String, Object>> rows = productionProductOutputMapper.selectDailyOutputStats(start, end);
|
if (rows != null) {
|
for (Map<String, Object> row : rows) {
|
quantity = quantity.add(toBigDecimal(row.get("quantity")));
|
scrapQty = scrapQty.add(toBigDecimal(row.get("scrapQty")));
|
}
|
}
|
|
Map<String, BigDecimal> stats = new LinkedHashMap<>();
|
stats.put("quantity", quantity);
|
stats.put("scrapQty", scrapQty);
|
return stats;
|
}
|
|
private BigDecimal calcDeviceOee(LocalDate day) {
|
long totalDeviceCount = deviceLedgerMapper.selectCount(new LambdaQueryWrapper<>());
|
if (totalDeviceCount <= 0) {
|
return BigDecimal.ZERO;
|
}
|
|
Date start = Date.from(day.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
Date end = Date.from(day.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
|
|
List<DeviceRepair> repairList = deviceRepairMapper.selectList(new LambdaQueryWrapper<DeviceRepair>()
|
.select(DeviceRepair::getDeviceLedgerId)
|
.ge(DeviceRepair::getRepairTime, start)
|
.lt(DeviceRepair::getRepairTime, end)
|
.in(DeviceRepair::getStatus, 0, 3));
|
|
long repairingDeviceCount = repairList == null ? 0 : repairList.stream()
|
.map(DeviceRepair::getDeviceLedgerId)
|
.filter(Objects::nonNull)
|
.distinct()
|
.count();
|
|
long availableDeviceCount = Math.max(totalDeviceCount - repairingDeviceCount, 0);
|
return new BigDecimal(availableDeviceCount)
|
.multiply(new BigDecimal("100"))
|
.divide(new BigDecimal(totalDeviceCount), 2, RoundingMode.HALF_UP);
|
}
|
|
private BigDecimal calcOrderAchievementRate(LocalDate day) {
|
List<ProductionOrder> orderList = productionOrderMapper.selectList(new LambdaQueryWrapper<ProductionOrder>()
|
.select(ProductionOrder::getQuantity, ProductionOrder::getCompleteQuantity)
|
.ge(ProductionOrder::getCreateTime, day.atStartOfDay())
|
.lt(ProductionOrder::getCreateTime, day.plusDays(1).atStartOfDay())
|
.ne(ProductionOrder::getStatus, ORDER_STATUS_PAUSED));
|
|
BigDecimal totalQuantity = BigDecimal.ZERO;
|
BigDecimal totalCompleteQuantity = BigDecimal.ZERO;
|
if (orderList != null) {
|
for (ProductionOrder order : orderList) {
|
totalQuantity = totalQuantity.add(zeroIfNull(order.getQuantity()));
|
totalCompleteQuantity = totalCompleteQuantity.add(zeroIfNull(order.getCompleteQuantity()));
|
}
|
}
|
return calcRate(totalCompleteQuantity, totalQuantity);
|
}
|
|
private BigDecimal calcDefectRate(LocalDate day) {
|
Map<String, BigDecimal> stats = loadOutputStats(day, day.plusDays(1));
|
BigDecimal quantity = stats.get("quantity");
|
BigDecimal scrapQty = stats.get("scrapQty");
|
return calcRate(scrapQty, quantity.add(scrapQty));
|
}
|
|
private Map<String, Object> buildRealtimeMetric(BigDecimal value, BigDecimal change) {
|
Map<String, Object> metric = new LinkedHashMap<>();
|
metric.put("value", scale(value));
|
metric.put("compareYesterday", scale(change));
|
return metric;
|
}
|
|
private BigDecimal calcRate(BigDecimal numerator, BigDecimal denominator) {
|
if (denominator == null || denominator.compareTo(BigDecimal.ZERO) <= 0) {
|
return BigDecimal.ZERO;
|
}
|
return zeroIfNull(numerator)
|
.multiply(new BigDecimal("100"))
|
.divide(denominator, 2, RoundingMode.HALF_UP);
|
}
|
|
private BigDecimal toBigDecimal(Object value) {
|
if (value == null) {
|
return BigDecimal.ZERO;
|
}
|
if (value instanceof BigDecimal) {
|
return (BigDecimal) value;
|
}
|
if (value instanceof Number) {
|
return BigDecimal.valueOf(((Number) value).doubleValue());
|
}
|
try {
|
return new BigDecimal(String.valueOf(value));
|
} catch (Exception ex) {
|
return BigDecimal.ZERO;
|
}
|
}
|
|
private Integer toInteger(Object value) {
|
if (value == null) {
|
return null;
|
}
|
if (value instanceof Integer) {
|
return (Integer) value;
|
}
|
if (value instanceof Number) {
|
return ((Number) value).intValue();
|
}
|
try {
|
return Integer.valueOf(String.valueOf(value));
|
} catch (Exception ex) {
|
return null;
|
}
|
}
|
|
private long toLong(Object value) {
|
if (value == null) {
|
return 0L;
|
}
|
if (value instanceof Long) {
|
return (Long) value;
|
}
|
if (value instanceof Number) {
|
return ((Number) value).longValue();
|
}
|
try {
|
return Long.parseLong(String.valueOf(value));
|
} catch (Exception ex) {
|
return 0L;
|
}
|
}
|
|
private BigDecimal zeroIfNull(BigDecimal value) {
|
return value == null ? BigDecimal.ZERO : value;
|
}
|
|
private BigDecimal scale(BigDecimal value) {
|
return zeroIfNull(value).setScale(2, RoundingMode.HALF_UP);
|
}
|
|
}
|