From 04dce61c02c10832665cdaf1aabf5b7e9b31da47 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期三, 21 一月 2026 16:17:19 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New
---
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java | 37
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java | 7
src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java | 3
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java | 11
src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java | 5
src/main/java/com/ruoyi/project/system/domain/SysDept.java | 12
src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java | 37 +
src/main/java/com/ruoyi/staff/vo/MonthlyTurnoverRateVo.java | 39 +
src/main/java/com/ruoyi/quality/dto/QualityMonthlyDetailDto.java | 29 +
src/main/java/com/ruoyi/quality/dto/QualityPassRateDto.java | 39 +
src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java | 10
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java | 40 -
src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java | 4
src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java | 100 ++++
src/main/java/com/ruoyi/staff/service/AnalyticsService.java | 20
src/main/resources/mapper/staff/StaffOnJobMapper.xml | 15
src/main/java/com/ruoyi/quality/dto/QualityMonthlyPassRateDto.java | 41 +
src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java | 14
src/main/java/com/ruoyi/quality/dto/QualityInspectStatDto.java | 24 +
src/main/java/com/ruoyi/quality/service/QualityReportService.java | 23
src/main/resources/mapper/quality/QualityTestStandardMapper.xml | 1
src/main/resources/mapper/staff/StaffLeaveMapper.xml | 20
src/main/java/com/ruoyi/quality/controller/QualityReportController.java | 62 ++
src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java | 3
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java | 14
src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java | 18
src/main/java/com/ruoyi/staff/controller/AnalyticsController.java | 32 +
src/main/java/com/ruoyi/quality/dto/QualityParameterStatDto.java | 26 +
src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java | 8
src/main/java/com/ruoyi/quality/dto/QualityTopParameterDto.java | 24 +
src/main/resources/mapper/quality/QualityInspectMapper.xml | 290 ++++++++++++
src/main/java/com/ruoyi/staff/vo/TotalTurnoverRateVo.java | 19
src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java | 10
src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java | 102 ++++
src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java | 145 ++++++
src/main/resources/mapper/production/ProductionProductMainMapper.xml | 7
src/main/java/com/ruoyi/quality/dto/QualityMonthlyPassRateWrapperDto.java | 28 +
src/main/resources/mapper/system/SysDeptMapper.xml | 23
38 files changed, 1,249 insertions(+), 93 deletions(-)
diff --git a/src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java b/src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java
index 44d3098..5c043fb 100644
--- a/src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java
+++ b/src/main/java/com/ruoyi/common/enums/StaffLeaveReason.java
@@ -25,4 +25,18 @@
public String getInfo() {
return info;
}
+
+ /**
+ * 鏍规嵁code鑾峰彇鏋氫妇瀹炰緥
+ * @param code 绂昏亴鍘熷洜缂栫爜
+ * @return 瀵瑰簲鐨勬灇涓惧疄渚嬶紝鑻ユ湭鎵惧埌鍒欒繑鍥瀗ull
+ */
+ public static StaffLeaveReason getByCode(String code) {
+ for (StaffLeaveReason reason : StaffLeaveReason.values()) {
+ if (reason.getCode().equals(code)) {
+ return reason;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
index c9d1268..2bdefa3 100644
--- a/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
+++ b/src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.production.dto.ProductionProductMainDto;
+import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.production.pojo.ProductionProductMain;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -19,4 +20,11 @@
* 鏍规嵁宸ュ崟ID鎵归噺鍒犻櫎鐢熶骇涓昏〃鏁版嵁
*/
int deleteByWorkOrderIds(@Param("workOrderIds") List<Long> workOrderIds);
+
+ /**
+ * 鏍规嵁鎶ュ伐id鏌ヨ鐢熶骇璁㈠崟
+ * @param productMainId
+ * @return
+ */
+ ProductOrder getOrderByMainId(@Param("productMainId") Long productMainId);
}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
index 67d8bba..5d1e454 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -75,6 +75,7 @@
private QualityTestStandardParamMapper qualityTestStandardParamMapper;
private QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
+ private QualityTestStandardMapper qualityTestStandardMapper;
private QualityInspectParamMapper qualityInspectParamMapper;
@@ -189,12 +190,15 @@
productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId());
productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO);
productionProductOutputMapper.insert(productionProductOutput);
+ /*鏂板璐ㄦ*/
//瀵瑰簲鐨勮繃绋嬫鎴栬�呭嚭鍘傛
List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
int inspectType = 1;
+ String process = productProcess.getName();//宸ュ簭
if (productProcessRouteItem.getDragSort()==productProcessRouteItems.size()){
//鏈�鍚庝竴閬撳伐搴忕敓鎴愬嚭鍘傛
inspectType = 2;
+ process = null;
}
Product product = productMapper.selectById(productModel.getProductId());
QualityInspect qualityInspect = new QualityInspect();
@@ -209,12 +213,12 @@
qualityInspect.setProductMainId(productionProductMain.getId());
qualityInspect.setProductModelId(productModel.getId());
qualityInspectMapper.insert(qualityInspect);
- List<QualityTestStandardBinding> qualityTestStandardBindings = qualityTestStandardBindingMapper.selectList(
- new LambdaQueryWrapper<QualityTestStandardBinding>()
- .eq(QualityTestStandardBinding::getProductId, product.getId()));
- if (qualityTestStandardBindings.size()>0){
+ List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType,process);
+ if (qualityTestStandard.size()>0){
+ qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
+ qualityInspectMapper.updateById(qualityInspect);
qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
- .eq(QualityTestStandardParam::getTestStandardId,qualityTestStandardBindings.get(0).getTestStandardId()))
+ .eq(QualityTestStandardParam::getTestStandardId,qualityTestStandard.get(0).getId()))//榛樿鑾峰彇鏈�鏂扮殑
.forEach(qualityTestStandardParam -> {
QualityInspectParam param = new QualityInspectParam();
BeanUtils.copyProperties(qualityTestStandardParam, param);
diff --git a/src/main/java/com/ruoyi/project/system/domain/SysDept.java b/src/main/java/com/ruoyi/project/system/domain/SysDept.java
index e2c6b2b..54e53a7 100644
--- a/src/main/java/com/ruoyi/project/system/domain/SysDept.java
+++ b/src/main/java/com/ruoyi/project/system/domain/SysDept.java
@@ -54,6 +54,9 @@
/** 閮ㄩ棬缂栧彿 */
private String deptNick;
+
+ /** 鍛樺伐鏁伴噺 */
+ private Integer staffCount;
/** 瀛愰儴闂� */
private List<SysDept> children = new ArrayList<SysDept>();
@@ -192,6 +195,14 @@
this.deptNick = deptNick;
}
+ public Integer getStaffCount() {
+ return staffCount;
+ }
+
+ public void setStaffCount(Integer staffCount) {
+ this.staffCount = staffCount;
+ }
+
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -199,6 +210,7 @@
.append("parentId", getParentId())
.append("ancestors", getAncestors())
.append("deptName", getDeptName())
+ .append("staffCount", getStaffCount())
.append("orderNum", getOrderNum())
.append("leader", getLeader())
.append("phone", getPhone())
diff --git a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
index 9c115c0..257313f 100644
--- a/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -108,6 +108,7 @@
private final QualityInspectMapper qualityInspectMapper;
private final QualityTestStandardBindingMapper qualityTestStandardBindingMapper;
private final QualityTestStandardParamMapper qualityTestStandardParamMapper;
+ private final QualityTestStandardMapper qualityTestStandardMapper;
private final QualityInspectParamMapper qualityInspectParamMapper;
private final ProcurementRecordMapper procurementRecordStorageMapper;
@@ -229,12 +230,12 @@
qualityInspect.setUnit(saleProduct.getUnit());
qualityInspect.setQuantity(saleProduct.getQuantity());
qualityInspectMapper.insert(qualityInspect);
- List<QualityTestStandardBinding> qualityTestStandardBindings = qualityTestStandardBindingMapper.selectList(
- new LambdaQueryWrapper<QualityTestStandardBinding>()
- .eq(QualityTestStandardBinding::getProductId, saleProduct.getProductId()));
- if (qualityTestStandardBindings.size()>0){
+ List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(saleProduct.getProductId(), 0,null);
+ if (qualityTestStandard.size()>0){
+ qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId());
+ qualityInspectMapper.updateById(qualityInspect);
qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery()
- .eq(QualityTestStandardParam::getTestStandardId,qualityTestStandardBindings.get(0).getTestStandardId()))
+ .eq(QualityTestStandardParam::getTestStandardId,qualityTestStandard.get(0).getId()))
.forEach(qualityTestStandardParam -> {
QualityInspectParam param = new QualityInspectParam();
com.ruoyi.common.utils.bean.BeanUtils.copyProperties(qualityTestStandardParam, param);
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityReportController.java b/src/main/java/com/ruoyi/quality/controller/QualityReportController.java
index fa6820f..b3e7025 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityReportController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityReportController.java
@@ -1,15 +1,12 @@
package com.ruoyi.quality.controller;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.framework.web.domain.AjaxResult;
-import com.ruoyi.quality.pojo.QualityTestStandardParam;
import com.ruoyi.quality.service.QualityReportService;
-import com.ruoyi.quality.service.QualityTestStandardParamService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
/**
* <p>
@@ -19,6 +16,7 @@
* @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
* @since 2026-01-14 03:39:49
*/
+@Api(tags = "璐ㄩ噺绠$悊")
@RestController
@RequestMapping("/qualityReport")
public class QualityReportController {
@@ -26,6 +24,58 @@
@Autowired
private QualityReportService qualityReportService;
+ /**
+ * 鑾峰彇妫�楠岀粺璁℃暟鎹�
+ */
+ @ApiOperation("鑾峰彇妫�楠岀粺璁℃暟鎹�")
+ @GetMapping("/getInspectStatistics")
+ public AjaxResult getInspectStatistics() {
+ return AjaxResult.success(qualityReportService.getInspectStatistics());
+ }
+ /**
+ * 鑾峰彇鍚堟牸鐜囩粺璁℃暟鎹�
+ */
+ @ApiOperation("鑾峰彇鍚堟牸鐜囩粺璁℃暟鎹�")
+ @GetMapping("/getPassRateStatistics")
+ public AjaxResult getPassRateStatistics() {
+ return AjaxResult.success(qualityReportService.getPassRateStatistics());
+ }
+
+ /**
+ * 鑾峰彇鏈堝害鍚堟牸鐜囩粺璁℃暟鎹�
+ */
+ @ApiOperation("鑾峰彇鏈堝害鍚堟牸鐜囩粺璁℃暟鎹�")
+ @GetMapping("/getMonthlyPassRateStatistics")
+ public AjaxResult getMonthlyPassRateStatistics(@RequestParam("year") String year) {
+ return AjaxResult.success(qualityReportService.getMonthlyPassRateStatistics(year));
+ }
+
+ /**
+ * 鑾峰彇骞村害鎬诲悎鏍肩巼缁熻鏁版嵁
+ */
+ @ApiOperation("鑾峰彇骞村害鎬诲悎鏍肩巼缁熻鏁版嵁")
+ @GetMapping("/getYearlyPassRateStatistics")
+ public AjaxResult getYearlyPassRateStatistics(@RequestParam("year") String year) {
+ return AjaxResult.success(qualityReportService.getYearlyPassRateStatistics(year));
+ }
+
+ /**
+ * 鑾峰彇鏈堝害瀹屾垚鏄庣粏鏁版嵁
+ */
+ @ApiOperation("鑾峰彇鏈堝害瀹屾垚鏄庣粏鏁版嵁")
+ @GetMapping("/getMonthlyCompletionDetails")
+ public AjaxResult getMonthlyCompletionDetails(@RequestParam("year") String year) {
+ return AjaxResult.success(qualityReportService.getMonthlyCompletionDetails(year));
+ }
+
+ /**
+ * 鑾峰彇鐑偣妫�娴嬫寚鏍囩粺璁�
+ */
+ @ApiOperation("鑾峰彇鐑偣妫�娴嬫寚鏍囩粺璁�")
+ @GetMapping("/getTopParameters")
+ public AjaxResult getTopParameters(@RequestParam("inspectType") Integer inspectType) {
+ return AjaxResult.success(qualityReportService.getTopParameters(inspectType));
+ }
}
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java b/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
index 7a42873..1cce084 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
@@ -86,5 +86,15 @@
qualityUnqualifiedService.qualityUnqualifiedExport(response, qualityUnqualified);
}
+ /**
+ * 涓嶅悎鏍肩鐞嗗鐞�
+ * @param qualityUnqualified
+ * @return
+ */
+ @PostMapping("/deal")
+ public AjaxResult deal(@RequestBody QualityUnqualified qualityUnqualified) {
+ return AjaxResult.success(qualityUnqualifiedService.deal(qualityUnqualified));
+ }
+
}
diff --git a/src/main/java/com/ruoyi/quality/dto/QualityInspectStatDto.java b/src/main/java/com/ruoyi/quality/dto/QualityInspectStatDto.java
new file mode 100644
index 0000000..9b39c94
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/dto/QualityInspectStatDto.java
@@ -0,0 +1,24 @@
+package com.ruoyi.quality.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "QualityInspectStatDto", description = "璐ㄩ噺妫�楠岀粺璁TO")
+public class QualityInspectStatDto implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "绫诲埆(0:鍘熸潗鏂欐楠�;1:杩囩▼妫�楠�;2:鍑哄巶妫�楠�)")
+ private Integer inspectType;
+
+ @ApiModelProperty(value = "鎬绘暟閲�")
+ private BigDecimal totalCount;
+
+ @ApiModelProperty(value = "宸插畬鎴愭暟閲�")
+ private BigDecimal completedCount;
+}
diff --git a/src/main/java/com/ruoyi/quality/dto/QualityMonthlyDetailDto.java b/src/main/java/com/ruoyi/quality/dto/QualityMonthlyDetailDto.java
new file mode 100644
index 0000000..a89d25d
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/dto/QualityMonthlyDetailDto.java
@@ -0,0 +1,29 @@
+package com.ruoyi.quality.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 璐ㄩ噺鏈堝害瀹屾垚鏄庣粏DTO
+ */
+@Data
+@ApiModel(value = "QualityMonthlyDetailDto", description = "璐ㄩ噺鏈堝害瀹屾垚鏄庣粏DTO")
+public class QualityMonthlyDetailDto implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "鏈堜唤")
+ private String month;
+
+ @ApiModelProperty(value = "鍘熸潗鏂欐楠屽畬鎴愭暟")
+ private BigDecimal rawMaterialCount;
+
+ @ApiModelProperty(value = "杩囩▼妫�楠屽畬鎴愭暟")
+ private BigDecimal processCount;
+
+ @ApiModelProperty(value = "鍑哄巶妫�楠屽畬鎴愭暟")
+ private BigDecimal outgoingCount;
+}
diff --git a/src/main/java/com/ruoyi/quality/dto/QualityMonthlyPassRateDto.java b/src/main/java/com/ruoyi/quality/dto/QualityMonthlyPassRateDto.java
new file mode 100644
index 0000000..9591a73
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/dto/QualityMonthlyPassRateDto.java
@@ -0,0 +1,41 @@
+package com.ruoyi.quality.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 璐ㄩ噺鏈堝害鍚堟牸鐜囩粺璁TO
+ */
+@Data
+@ApiModel(value = "QualityMonthlyPassRateDto", description = "璐ㄩ噺鏈堝害鍚堟牸鐜囩粺璁TO")
+public class QualityMonthlyPassRateDto implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "鏈堜唤(涓�鏈�, 浜屾湀...)")
+ private String month;
+
+ @ApiModelProperty(value = "绫诲埆(0:鍘熸潗鏂欐楠�;1:杩囩▼妫�楠�;2:鍑哄巶妫�楠�)")
+ private Integer inspectType;
+
+ @ApiModelProperty(value = "鎬绘暟閲�")
+ private BigDecimal totalCount;
+
+ @ApiModelProperty(value = "宸插畬鎴愭暟閲�")
+ private BigDecimal completedCount;
+
+ @ApiModelProperty(value = "鍚堟牸鏁伴噺")
+ private BigDecimal qualifiedCount;
+
+ @ApiModelProperty(value = "涓嶅悎鏍兼暟閲�")
+ private BigDecimal unqualifiedCount;
+
+ @ApiModelProperty(value = "瀹屾垚鍗犳瘮")
+ private BigDecimal completionRate;
+
+ @ApiModelProperty(value = "鍚堟牸鐜囧崰姣�")
+ private BigDecimal passRate;
+}
diff --git a/src/main/java/com/ruoyi/quality/dto/QualityMonthlyPassRateWrapperDto.java b/src/main/java/com/ruoyi/quality/dto/QualityMonthlyPassRateWrapperDto.java
new file mode 100644
index 0000000..0bdbc39
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/dto/QualityMonthlyPassRateWrapperDto.java
@@ -0,0 +1,28 @@
+package com.ruoyi.quality.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 璐ㄩ噺鏈堝害鍚堟牸鐜囧寘瑁匘TO锛堟寜鏈堝垎缁勶級
+ */
+@Data
+@ApiModel(value = "QualityMonthlyPassRateWrapperDto", description = "璐ㄩ噺鏈堝害鍚堟牸鐜囧寘瑁匘TO锛堟寜鏈堝垎缁勶級")
+public class QualityMonthlyPassRateWrapperDto implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "鏈堜唤")
+ private String month;
+
+ @ApiModelProperty(value = "鍘熸潗鏂欐楠屾暟鎹�")
+ private QualityPassRateDto rawMaterial;
+
+ @ApiModelProperty(value = "杩囩▼妫�楠屾暟鎹�")
+ private QualityPassRateDto process;
+
+ @ApiModelProperty(value = "鍑哄巶妫�楠屾暟鎹�")
+ private QualityPassRateDto outgoing;
+}
diff --git a/src/main/java/com/ruoyi/quality/dto/QualityParameterStatDto.java b/src/main/java/com/ruoyi/quality/dto/QualityParameterStatDto.java
new file mode 100644
index 0000000..0675981
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/dto/QualityParameterStatDto.java
@@ -0,0 +1,26 @@
+package com.ruoyi.quality.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 妫�楠屾寚鏍囩粺璁TO
+ */
+@Data
+@ApiModel(value = "QualityParameterStatDto", description = "妫�楠屾寚鏍囩粺璁TO")
+public class QualityParameterStatDto implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "鎸囨爣鍚嶇О")
+ private String name;
+
+ @ApiModelProperty(value = "鏁伴噺")
+ private BigDecimal count;
+
+ @ApiModelProperty(value = "鐧惧垎姣�")
+ private BigDecimal percentage;
+}
diff --git a/src/main/java/com/ruoyi/quality/dto/QualityPassRateDto.java b/src/main/java/com/ruoyi/quality/dto/QualityPassRateDto.java
new file mode 100644
index 0000000..354579e
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/dto/QualityPassRateDto.java
@@ -0,0 +1,39 @@
+package com.ruoyi.quality.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 璐ㄩ噺鍚堟牸鐜囩粺璁TO
+ */
+@Data
+@ApiModel(value = "QualityPassRateDto", description = "璐ㄩ噺鍚堟牸鐜囩粺璁TO")
+public class QualityPassRateDto implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "绫诲埆(0:鍘熸潗鏂欐楠�;1:杩囩▼妫�楠�;2:鍑哄巶妫�楠�)")
+ private Integer inspectType;
+
+ @ApiModelProperty(value = "鎬绘暟閲�")
+ private BigDecimal totalCount;
+
+ @ApiModelProperty(value = "宸插畬鎴愭暟閲�")
+ private BigDecimal completedCount;
+
+ @ApiModelProperty(value = "鍚堟牸鏁伴噺")
+ private BigDecimal qualifiedCount;
+
+ @ApiModelProperty(value = "涓嶅悎鏍兼暟閲�")
+ private BigDecimal unqualifiedCount;
+
+ @ApiModelProperty(value = "瀹屾垚鍗犳瘮")
+ private BigDecimal completionRate;
+
+ @ApiModelProperty(value = "鍚堟牸鐜囧崰姣�")
+ private BigDecimal passRate;
+}
diff --git a/src/main/java/com/ruoyi/quality/dto/QualityTopParameterDto.java b/src/main/java/com/ruoyi/quality/dto/QualityTopParameterDto.java
new file mode 100644
index 0000000..0be4e8b
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/dto/QualityTopParameterDto.java
@@ -0,0 +1,24 @@
+package com.ruoyi.quality.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 璐ㄦ鐑偣鎸囨爣缁熻缁撴灉DTO (鍗曠被鍨�)
+ */
+@Data
+@ApiModel(value = "QualityTopParameterDto", description = "璐ㄦ鐑偣鎸囨爣缁熻缁撴灉DTO (鍗曠被鍨�)")
+public class QualityTopParameterDto implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "鎬绘娴嬮」娆℃暟閲�")
+ private BigDecimal totalCount;
+
+ @ApiModelProperty(value = "鎸囨爣缁熻鍒楄〃 (Top 4 + 鍏朵粬)")
+ private List<QualityParameterStatDto> list;
+}
diff --git a/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java b/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
index fdc57da..2958970 100644
--- a/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
+++ b/src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
@@ -4,9 +4,14 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.quality.pojo.QualityInspect;
-import com.ruoyi.quality.pojo.QualityTestStandard;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
+
+import com.ruoyi.quality.dto.QualityInspectStatDto;
+import com.ruoyi.quality.dto.QualityPassRateDto;
+import com.ruoyi.quality.dto.QualityMonthlyPassRateDto;
+import com.ruoyi.quality.dto.QualityMonthlyDetailDto;
+import com.ruoyi.quality.dto.QualityParameterStatDto;
import java.util.List;
@@ -22,4 +27,34 @@
* 鏍规嵁鐢熶骇涓昏〃ID鎵归噺鍒犻櫎杩囩▼妫�楠�
*/
int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
+
+ /**
+ * 鑾峰彇妫�楠岀粺璁℃暟鎹�
+ */
+ List<QualityInspectStatDto> getInspectStatistics();
+
+ /**
+ * 鑾峰彇鍚堟牸鐜囩粺璁℃暟鎹�
+ */
+ List<QualityPassRateDto> getPassRateStatistics();
+
+ /**
+ * 鑾峰彇鏈堝害鍚堟牸鐜囩粺璁℃暟鎹�
+ */
+ List<QualityMonthlyPassRateDto> getMonthlyPassRateStatistics(@Param("year") String year);
+
+ /**
+ * 鑾峰彇骞村害鍚堟牸鐜囩粺璁℃暟鎹�
+ */
+ List<QualityPassRateDto> getYearlyPassRateStatistics(@Param("year") String year);
+
+ /**
+ * 鑾峰彇鏈堝害瀹屾垚鏄庣粏鏁版嵁
+ */
+ List<QualityMonthlyDetailDto> getMonthlyCompletionDetails(@Param("year") String year);
+
+ /**
+ * 鑾峰彇鐑偣妫�娴嬫寚鏍� Top 4 + 鍏朵粬
+ */
+ List<QualityParameterStatDto> getTopParameters(@Param("inspectType") Integer inspectType);
}
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java b/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
index 5636c2f..eaebece 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityUnqualified.java
@@ -133,5 +133,6 @@
@TableField(fill = FieldFill.INSERT)
private Long tenantId;
-
+ @ApiModelProperty("鍏宠仈妫�娴媔d")
+ private Long inspectId;
}
diff --git a/src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java b/src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java
index 3aed832..7cd7f79 100644
--- a/src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java
+++ b/src/main/java/com/ruoyi/quality/service/IQualityUnqualifiedService.java
@@ -14,4 +14,7 @@
IPage<QualityUnqualified> qualityUnqualifiedListPage(Page page, QualityUnqualified qualityUnqualified);
void qualityUnqualifiedExport(HttpServletResponse response, QualityUnqualified qualityUnqualified);
+
+ int deal(QualityUnqualified qualityUnqualified);
+
}
diff --git a/src/main/java/com/ruoyi/quality/service/QualityReportService.java b/src/main/java/com/ruoyi/quality/service/QualityReportService.java
index 4bc70f5..053359a 100644
--- a/src/main/java/com/ruoyi/quality/service/QualityReportService.java
+++ b/src/main/java/com/ruoyi/quality/service/QualityReportService.java
@@ -1,7 +1,13 @@
package com.ruoyi.quality.service;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.ruoyi.quality.pojo.QualityTestStandardParam;
+import com.ruoyi.quality.dto.QualityInspectStatDto;
+import com.ruoyi.quality.dto.QualityPassRateDto;
+import com.ruoyi.quality.dto.QualityMonthlyDetailDto;
+import com.ruoyi.quality.dto.QualityParameterStatDto;
+import com.ruoyi.quality.dto.QualityMonthlyPassRateWrapperDto;
+import com.ruoyi.quality.dto.QualityTopParameterDto;
+
+import java.util.List;
/**
* <p>
@@ -11,6 +17,17 @@
* @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
* @since 2026-01-13 03:39:49
*/
-public interface QualityReportService {
+public interface QualityReportService {
+ List<QualityInspectStatDto> getInspectStatistics();
+
+ List<QualityPassRateDto> getPassRateStatistics();
+
+ List<QualityMonthlyPassRateWrapperDto> getMonthlyPassRateStatistics(String year);
+
+ List<QualityPassRateDto> getYearlyPassRateStatistics(String year);
+
+ List<QualityMonthlyDetailDto> getMonthlyCompletionDetails(String year);
+
+ QualityTopParameterDto getTopParameters(Integer inspectType);
}
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
index 48b055b..1ae24e9 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -96,6 +96,7 @@
List<QualityInspectParam> inspectParams = qualityInspectParamService.list(Wrappers.<QualityInspectParam>lambdaQuery().eq(QualityInspectParam::getInspectId, inspect.getId()));
String text = inspectParams.stream().map(QualityInspectParam::getParameterItem).collect(Collectors.joining(","));
qualityUnqualified.setDefectivePhenomena(text+"杩欎簺鎸囨爣涓瓨鍦ㄤ笉鍚堟牸");//涓嶅悎鏍肩幇璞�
+ qualityUnqualified.setInspectId(qualityInspect.getId());
qualityUnqualifiedMapper.insert(qualityUnqualified);
}
@@ -158,22 +159,26 @@
}else if (qualityInspect.getInspectType() == 2) {
//鏌ヨUnitPrice/TotalPrice
- SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectSalesLedgerProductByMainId(qualityInspect.getProductMainId());
- ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
- procurementRecordOutAdd.setType(2);
- procurementRecordOutAdd.setTypeName("鐢熶骇鍑哄巶妫�楠屽悎鏍煎叆搴�");
- procurementRecordOutAdd.setNickName(loginUser.getNickName());
- List<Details> details = new ArrayList<>();
- Details details1 = new Details();
- details1.setInboundQuantity(qualityInspect.getQuantity());
- details1.setId(Math.toIntExact(salesLedgerProduct.getId()));
- details1.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
- details1.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
- details1.setProductModelId(salesLedgerProduct.getProductModelId());
- details.add(details1);
- procurementRecordOutAdd.setDetails(details);
- procurementRecordOutAdd.setQualityInspectId(qualityInspect.getId());
- procurementRecordService.add(procurementRecordOutAdd);
+ if (ObjectUtils.isNull(qualityInspect.getProductMainId())){
+ //濡傛灉鏄墜鍔ㄦ柊澧炵殑鍑哄巶妫�
+ }else {
+ SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectSalesLedgerProductByMainId(qualityInspect.getProductMainId());
+ ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
+ procurementRecordOutAdd.setType(2);
+ procurementRecordOutAdd.setTypeName("鐢熶骇鍑哄巶妫�楠屽悎鏍煎叆搴�");
+ procurementRecordOutAdd.setNickName(loginUser.getNickName());
+ List<Details> details = new ArrayList<>();
+ Details details1 = new Details();
+ details1.setInboundQuantity(qualityInspect.getQuantity());
+ details1.setId(Math.toIntExact(salesLedgerProduct.getId()));
+ details1.setUnitPrice(salesLedgerProduct.getTaxInclusiveUnitPrice());
+ details1.setTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice());
+ details1.setProductModelId(salesLedgerProduct.getProductModelId());
+ details.add(details1);
+ procurementRecordOutAdd.setDetails(details);
+ procurementRecordOutAdd.setQualityInspectId(qualityInspect.getId());
+ procurementRecordService.add(procurementRecordOutAdd);
+ }
}
qualityInspect.setInspectState(1);//宸叉彁浜�
return qualityInspectMapper.updateById(qualityInspect);
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java
index dfdfaf0..ee11f8e 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityReportServiceImpl.java
@@ -1,9 +1,109 @@
package com.ruoyi.quality.service.impl;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.quality.dto.QualityPassRateDto;
+import com.ruoyi.quality.dto.QualityInspectStatDto;
+import com.ruoyi.quality.dto.QualityMonthlyPassRateDto;
+import com.ruoyi.quality.dto.QualityMonthlyDetailDto;
+import com.ruoyi.quality.dto.QualityParameterStatDto;
+import com.ruoyi.quality.dto.QualityMonthlyPassRateWrapperDto;
+import com.ruoyi.quality.dto.QualityTopParameterDto;
+import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.service.QualityReportService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
@Service
public class QualityReportServiceImpl implements QualityReportService {
+
+ @Autowired
+ private QualityInspectMapper qualityInspectMapper;
+
+ @Override
+ public List<QualityInspectStatDto> getInspectStatistics() {
+ return qualityInspectMapper.getInspectStatistics();
+ }
+
+ @Override
+ public List<QualityPassRateDto> getPassRateStatistics() {
+ return qualityInspectMapper.getPassRateStatistics();
+ }
+
+ @Override
+ public List<QualityMonthlyPassRateWrapperDto> getMonthlyPassRateStatistics(String year) {
+ if (StringUtils.isEmpty(year)) {
+ return new ArrayList<>();
+ }
+ List<QualityMonthlyPassRateDto> flatData = qualityInspectMapper.getMonthlyPassRateStatistics(year);
+
+ // 鎸夋湀浠藉垎缁勶紝骞朵繚鎸侀『搴�
+ Map<String, List<QualityMonthlyPassRateDto>> groupedByMonth = flatData.stream()
+ .collect(Collectors.groupingBy(QualityMonthlyPassRateDto::getMonth, LinkedHashMap::new, Collectors.toList()));
+
+ List<QualityMonthlyPassRateWrapperDto> result = new ArrayList<>();
+
+ groupedByMonth.forEach((month, dtos) -> {
+ QualityMonthlyPassRateWrapperDto wrapper = new QualityMonthlyPassRateWrapperDto();
+ wrapper.setMonth(month);
+
+ for (QualityMonthlyPassRateDto dto : dtos) {
+ QualityPassRateDto passRateDto = new QualityPassRateDto();
+ BeanUtils.copyProperties(dto, passRateDto);
+
+ if (dto.getInspectType() == 0) {
+ wrapper.setRawMaterial(passRateDto);
+ } else if (dto.getInspectType() == 1) {
+ wrapper.setProcess(passRateDto);
+ } else if (dto.getInspectType() == 2) {
+ wrapper.setOutgoing(passRateDto);
+ }
+ }
+ result.add(wrapper);
+ });
+
+ return result;
+ }
+
+ @Override
+ public List<QualityPassRateDto> getYearlyPassRateStatistics(String year) {
+ if (StringUtils.isEmpty(year)) {
+ return new ArrayList<>();
+ }
+ return qualityInspectMapper.getYearlyPassRateStatistics(year);
+ }
+
+ @Override
+ public List<QualityMonthlyDetailDto> getMonthlyCompletionDetails(String year) {
+ if (StringUtils.isEmpty(year)) {
+ return new ArrayList<>();
+ }
+ return qualityInspectMapper.getMonthlyCompletionDetails(year);
+ }
+
+ @Override
+ public QualityTopParameterDto getTopParameters(Integer inspectType) {
+ if (inspectType == null) {
+ return new QualityTopParameterDto();
+ }
+ List<QualityParameterStatDto> list = qualityInspectMapper.getTopParameters(inspectType);
+
+ BigDecimal total = list.stream()
+ .map(QualityParameterStatDto::getCount)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+ QualityTopParameterDto result = new QualityTopParameterDto();
+ result.setTotalCount(total);
+ result.setList(list);
+
+ return result;
+ }
}
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
index a080dd3..796d798 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -1,10 +1,20 @@
package com.ruoyi.quality.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.production.mapper.ProductProcessRouteItemMapper;
+import com.ruoyi.production.mapper.ProductProcessRouteMapper;
+import com.ruoyi.production.mapper.ProductWorkOrderMapper;
+import com.ruoyi.production.mapper.ProductionProductMainMapper;
+import com.ruoyi.production.pojo.*;
+import com.ruoyi.production.service.ProductOrderService;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.mapper.QualityUnqualifiedMapper;
import com.ruoyi.quality.pojo.QualityInspect;
@@ -16,6 +26,9 @@
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.List;
@AllArgsConstructor
@@ -23,6 +36,13 @@
public class QualityUnqualifiedServiceImpl extends ServiceImpl<QualityUnqualifiedMapper, QualityUnqualified> implements IQualityUnqualifiedService {
private QualityUnqualifiedMapper qualityUnqualifiedMapper;
+ private IQualityInspectService qualityInspectService;
+ private ProductOrderService productOrderService;
+ private ProductionProductMainMapper productionProductMainMapper;
+ private ProductProcessRouteMapper productProcessRouteMapper;
+ private ProductProcessRouteItemMapper productProcessRouteItemMapper;
+ private ProductWorkOrderMapper productWorkOrderMapper;
+
@Override
public IPage<QualityUnqualified> qualityUnqualifiedListPage(Page page, QualityUnqualified qualityUnqualified) {
@@ -35,4 +55,86 @@
ExcelUtil<QualityUnqualified> util = new ExcelUtil<QualityUnqualified>(QualityUnqualified.class);
util.exportExcel(response, qualityUnqualifieds, "涓嶅悎鏍肩鐞嗗鍑�");
}
+
+ @Override
+ public int deal(QualityUnqualified qualityUnqualified) {
+ QualityUnqualified unqualified = qualityUnqualifiedMapper.selectById(qualityUnqualified.getId());
+ QualityInspect qualityInspect = qualityInspectService.getById(unqualified.getInspectId());
+ switch (qualityUnqualified.getDealResult()) {
+ case "杩斾慨":
+ case "杩斿伐":
+ //鍒ゆ柇璐ㄦ琛ㄦ槸鍚︽湁鐩稿叧鐨勬姤宸d,濡傛灉鏈夋姤宸d,閭d箞杩斿伐闇�瑕侀噸鏂板垱寤虹敓浜ц鍗曢噸鏂扮敓浜�
+ if (ObjectUtils.isNotNull(qualityInspect.getProductMainId())){
+ //杩斿伐闇�瑕侀噸鏂板垱寤虹敓浜ц鍗曢噸鏂扮敓浜�
+ ProductOrder productOrder = productionProductMainMapper.getOrderByMainId(qualityInspect.getProductMainId());
+ ProductOrder order = new ProductOrder();
+ BeanUtils.copyProperties(productOrder, order);
+ order.setId(null);
+ order.setQuantity(unqualified.getQuantity());
+ order.setCompleteQuantity(BigDecimal.ZERO);
+ order.setStartTime(null);
+ order.setEndTime(null);
+ productOrderService.save(order);
+ //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎涓昏〃
+ ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectList(Wrappers.<ProductProcessRoute>lambdaQuery().eq(ProductProcessRoute::getProductOrderId,productOrder.getId()).orderByDesc(ProductProcessRoute::getId)).get(0);
+ ProductProcessRoute newProcessRoute = new ProductProcessRoute();
+ BeanUtils.copyProperties(productProcessRoute, newProcessRoute);
+ newProcessRoute.setId(null);
+ newProcessRoute.setProductOrderId(order.getId());
+ productProcessRouteMapper.insert(newProcessRoute);
+ //鏂板鐢熶骇璁㈠崟涓嬬殑宸ヨ壓璺嚎瀛愯〃
+ List<ProductProcessRouteItem> processRouteItems = productProcessRouteItemMapper.selectList(new QueryWrapper<ProductProcessRouteItem>().lambda().eq(ProductProcessRouteItem::getProductRouteId, productProcessRoute.getId()));
+ // 鐢熸垚褰撳墠鏃ユ湡鐨勫墠缂�锛氬勾鏈堟棩
+ String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
+ for (ProductProcessRouteItem processRouteItem : processRouteItems) {
+ ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
+ BeanUtils.copyProperties(processRouteItem, productProcessRouteItem);
+ productProcessRouteItem.setId(null);
+ productProcessRouteItem.setProductRouteId(newProcessRoute.getId());
+ int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
+ if (insert > 0) {
+ // 鏌ヨ浠婃棩宸插瓨鍦ㄧ殑鏈�澶у伐鍗曞彿
+ QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
+ queryWrapper.likeRight("work_order_no", datePrefix)
+ .orderByDesc("work_order_no")
+ .last("LIMIT 1");
+ ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
+ int sequenceNumber = 1; // 榛樿搴忓彿
+ if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
+ String lastNo = lastWorkOrder.getWorkOrderNo().toString();
+ if (lastNo.startsWith(datePrefix)) {
+ String seqStr = lastNo.substring(datePrefix.length());
+ try {
+ sequenceNumber = Integer.parseInt(seqStr) + 1;
+ } catch (NumberFormatException e) {
+ sequenceNumber = 1;
+ }
+ }
+ }
+ // 鐢熸垚瀹屾暣鐨勫伐鍗曞彿
+ String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
+ ProductWorkOrder productWorkOrder = new ProductWorkOrder();
+ productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
+ productWorkOrder.setProductOrderId(order.getId());
+ productWorkOrder.setPlanQuantity(order.getQuantity());
+ productWorkOrder.setWorkOrderNo(workOrderNoStr);
+ productWorkOrder.setStatus(1);
+ productWorkOrderMapper.insert(productWorkOrder);
+ }
+ }
+ }
+ break;
+ case "鎶ュ簾":
+ break;
+ case "璁╂鏀捐":
+ //璋冪敤鎻愪氦鍚堟牸鐨勬帴鍙�
+ qualityInspect.setCheckResult("鍚堟牸");
+ qualityInspectService.submit(qualityInspect);
+ break;
+ default:
+ break;
+ }
+ qualityUnqualified.setInspectState(1);//宸插鐞�
+ return qualityUnqualifiedMapper.updateById(qualityUnqualified);
+ }
}
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
index 4a9b51f..8fdf4f9 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -146,45 +146,7 @@
// 2. 鎵ц鍒犻櫎鎿嶄綔
int result = salesLedgerProductMapper.deleteBatchIds(Arrays.asList(ids));
//鍒犻櫎瀵瑰簲鐨勭敓浜ц鍗�
- //鎵归噺鏌ヨproductOrder
- List<ProductOrder> productOrders = productOrderMapper.selectList(
- new LambdaQueryWrapper<ProductOrder>()
- .in(ProductOrder::getProductModelId, ids)
- );
-
- if (!CollectionUtils.isEmpty(productOrders)) {
- List<Long> orderIds = productOrders.stream()
- .map(ProductOrder::getId)
- .collect(Collectors.toList());
-
- // 鎵归噺鏌ヨprocessRouteItems
- List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
- new LambdaQueryWrapper<ProductProcessRouteItem>()
- .in(ProductProcessRouteItem::getProductOrderId, orderIds)
- );
-
- if (!CollectionUtils.isEmpty(allRouteItems)) {
- List<Long> routeItemIds = allRouteItems.stream()
- .map(ProductProcessRouteItem::getId)
- .collect(Collectors.toList());
-
- // 鎵归噺鍒犻櫎workOrder
- productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
- .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
- }
-
- // 鎵归噺鍒犻櫎productProcessRouteItem
- productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
- .in(ProductProcessRouteItem::getProductOrderId, orderIds));
-
- // 鎵归噺鍒犻櫎productProcessRoute
- productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
- .in(ProductProcessRoute::getProductOrderId, orderIds));
-
- // 鎵归噺鍒犻櫎productOrder
- productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
- .in(ProductOrder::getProductModelId, ids));
- }
+ deleteProductionData(Arrays.asList(ids));
// 3. 瀵规瘡涓富琛↖D杩涜閲戦鏇存柊
for (Long salesLedgerId : mainIds) {
diff --git a/src/main/java/com/ruoyi/staff/controller/AnalyticsController.java b/src/main/java/com/ruoyi/staff/controller/AnalyticsController.java
new file mode 100644
index 0000000..cfa802c
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/controller/AnalyticsController.java
@@ -0,0 +1,32 @@
+package com.ruoyi.staff.controller;
+
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.staff.service.AnalyticsService;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+@RestController
+@RequestMapping("/staff/analytics")
+public class AnalyticsController {
+
+ @Resource
+ private AnalyticsService analyticsService;
+
+ @GetMapping("/reason")
+ public AjaxResult staffLeaveReasonAnalytics() {
+ return AjaxResult.success(analyticsService.staffLeaveReasonAnalytics());
+ }
+
+ @GetMapping("/monthly_turnover_rate")
+ public AjaxResult getMonthlyTurnoverRateFor12Months() {
+ return AjaxResult.success(analyticsService.getMonthlyTurnoverRateFor12Months());
+ }
+
+ @GetMapping("/total_statistic")
+ public AjaxResult getTotalStatistic() {
+ return AjaxResult.success(analyticsService.getTotalStatistic());
+ }
+}
diff --git a/src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java b/src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java
index 7cdf48a..3685410 100644
--- a/src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java
+++ b/src/main/java/com/ruoyi/staff/dto/StaffLeaveDto.java
@@ -1,11 +1,8 @@
package com.ruoyi.staff.dto;
-import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.staff.pojo.StaffLeave;
import lombok.Data;
-
-import java.util.Date;
@Data
public class StaffLeaveDto extends StaffLeave {
@@ -95,4 +92,11 @@
*/
@Excel(name = "绱ф�ヨ仈绯讳汉鐢佃瘽", sort = 15)
private String emergencyContactPhone;
+
+ private int count;
+
+ /**
+ * 绂昏亴鍘熷洜鏂囨湰
+ */
+ private String reasonText;
}
diff --git a/src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java b/src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java
index e8d2854..170bbba 100644
--- a/src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java
+++ b/src/main/java/com/ruoyi/staff/mapper/StaffLeaveMapper.java
@@ -10,6 +10,7 @@
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
+import java.time.LocalDate;
import java.util.List;
@@ -18,4 +19,8 @@
IPage<StaffLeaveDto> staffLeaveListPage(Page page, @Param("c") StaffLeaveDto staffLeaveDto);
List<StaffLeaveDto> staffLeaveList(@Param("c") StaffLeaveDto staffLeaveDto);
+
+ List<StaffLeaveDto> staffLeaveReasonAnalytics();
+
+ Integer countLeaveByMonth(@Param("monthStart") LocalDate monthStart, @Param("monthEnd") LocalDate monthEnd);
}
diff --git a/src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java b/src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java
index 1451487..5bd15e4 100644
--- a/src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java
+++ b/src/main/java/com/ruoyi/staff/mapper/StaffOnJobMapper.java
@@ -8,6 +8,7 @@
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
+import java.time.LocalDate;
import java.util.List;
@Mapper
@@ -16,4 +17,19 @@
IPage<StaffOnJobDto> staffOnJobListPage(Page page, @Param("staffOnJob") StaffOnJob staffOnJob);
List<StaffOnJobDto> staffOnJobList(@Param("staffOnJob") StaffOnJob staffOnJob);
-}
+
+ /**
+ * 缁熻鎸囧畾鏃ユ湡鐨勫湪鑱屽憳宸ユ暟
+ * @param date 鏃ユ湡
+ * @return 鍦ㄨ亴鍛樺伐鏁�
+ */
+ Integer countOnJobStaffByDate(@Param("date") LocalDate date);
+
+ /**
+ * 缁熻鎸囧畾鏈堜唤鐨勬柊鍏ヨ亴鍛樺伐鏁�
+ * @param monthStart 鏈堜唤寮�濮嬫棩鏈�
+ * @param monthEnd 鏈堜唤缁撴潫鏃ユ湡
+ * @return 鏂板叆鑱屽憳宸ユ暟
+ */
+ Integer countNewHireByMonth(@Param("monthStart") LocalDate monthStart, @Param("monthEnd") LocalDate monthEnd);
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/staff/service/AnalyticsService.java b/src/main/java/com/ruoyi/staff/service/AnalyticsService.java
new file mode 100644
index 0000000..ee8ff83
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/service/AnalyticsService.java
@@ -0,0 +1,20 @@
+package com.ruoyi.staff.service;
+
+import com.ruoyi.staff.dto.StaffLeaveDto;
+import com.ruoyi.staff.vo.MonthlyTurnoverRateVo;
+import com.ruoyi.staff.vo.TotalTurnoverRateVo;
+
+import java.util.List;
+
+public interface AnalyticsService {
+
+ List<StaffLeaveDto> staffLeaveReasonAnalytics();
+
+ List<MonthlyTurnoverRateVo> getMonthlyTurnoverRateFor12Months();
+
+ /**
+ * 鏌ヨ鎬绘祦鍔ㄧ巼銆佹祦澶辩巼浠ュ強鍦ㄨ亴鍛樺伐鏁�
+ * @return 鎬荤粺璁$粨鏋�
+ */
+ TotalTurnoverRateVo getTotalStatistic();
+}
diff --git a/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java
new file mode 100644
index 0000000..13a440c
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/service/impl/AnalyticsServiceImpl.java
@@ -0,0 +1,145 @@
+package com.ruoyi.staff.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.enums.StaffLeaveReason;
+import com.ruoyi.staff.dto.StaffLeaveDto;
+import com.ruoyi.staff.mapper.StaffLeaveMapper;
+import com.ruoyi.staff.mapper.StaffOnJobMapper;
+import com.ruoyi.staff.pojo.StaffLeave;
+import com.ruoyi.staff.service.AnalyticsService;
+import com.ruoyi.staff.vo.MonthlyTurnoverRateVo;
+import com.ruoyi.staff.vo.TotalTurnoverRateVo;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+@AllArgsConstructor
+@Service
+public class AnalyticsServiceImpl extends ServiceImpl<StaffLeaveMapper, StaffLeave> implements AnalyticsService {
+ @Autowired
+ private StaffLeaveMapper staffLeaveMapper;
+
+ @Autowired
+ private StaffOnJobMapper staffOnJobMapper;
+
+ @Override
+ public List<StaffLeaveDto> staffLeaveReasonAnalytics() {
+ List<StaffLeaveDto> result = staffLeaveMapper.staffLeaveReasonAnalytics();
+ result.forEach(dto -> {
+ String reasonCode = dto.getReason();
+ StaffLeaveReason reasonEnum = StaffLeaveReason.getByCode(reasonCode);
+ if (reasonEnum != null) {
+ dto.setReasonText(reasonEnum.getInfo());
+ } else {
+ dto.setReasonText("鏈煡鍘熷洜");
+ }
+ });
+ return result;
+ }
+
+ @Override
+ public List<MonthlyTurnoverRateVo> getMonthlyTurnoverRateFor12Months() {
+ List<MonthlyTurnoverRateVo> result = new ArrayList<>();
+ LocalDate now = LocalDate.now();
+ DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
+
+ // 璁$畻杩�12涓湀鐨勬暟鎹�
+ for (int i = 11; i >= 0; i--) {
+ LocalDate currentMonth = now.minusMonths(i);
+ LocalDate monthStart = currentMonth.withDayOfMonth(1);
+ LocalDate monthEnd = currentMonth.withDayOfMonth(currentMonth.lengthOfMonth());
+
+ MonthlyTurnoverRateVo vo = new MonthlyTurnoverRateVo();
+ vo.setMonth(currentMonth.format(monthFormatter));
+ vo.setMonthStartDate(monthStart);
+ vo.setMonthEndDate(monthEnd);
+
+ // 鏈堝垵鍛樺伐鏁帮紙涓婃湀鏈湪鑱屽憳宸ユ暟锛�
+ LocalDate lastMonthEnd = monthStart.minusDays(1);
+ Integer beginMonthStaffCount = staffOnJobMapper.countOnJobStaffByDate(lastMonthEnd);
+ vo.setBeginMonthStaffCount(beginMonthStaffCount != null ? beginMonthStaffCount : 0);
+
+ // 鏈堟湯鍛樺伐鏁�
+ Integer endMonthStaffCount = staffOnJobMapper.countOnJobStaffByDate(monthEnd);
+ vo.setEndMonthStaffCount(endMonthStaffCount != null ? endMonthStaffCount : 0);
+
+ // 鏈堝害鍏ヨ亴鍛樺伐鏁�
+ Integer newHireCount = staffOnJobMapper.countNewHireByMonth(monthStart, monthEnd);
+ vo.setNewHireCount(newHireCount != null ? newHireCount : 0);
+
+ // 鏈堝害绂昏亴鍛樺伐鏁�
+ Integer leaveCount = staffLeaveMapper.countLeaveByMonth(monthStart, monthEnd);
+ vo.setLeaveCount(leaveCount != null ? leaveCount : 0);
+
+ // 璁$畻娴佸け鐜囷細娴佸け鐜� = 鏈堝害绂昏亴鍛樺伐鏁� / 鏈堝垵鍛樺伐鏁� * 100%
+ Double turnoverRate = 0.0;
+ if (vo.getBeginMonthStaffCount() > 0) {
+ turnoverRate = (double) vo.getLeaveCount() / vo.getBeginMonthStaffCount() * 100;
+ // 淇濈暀涓や綅灏忔暟
+ turnoverRate = Math.round(turnoverRate * 100.0) / 100.0;
+ }
+ vo.setTurnoverRate(turnoverRate);
+
+ // 璁$畻娴佸姩鐜囷細娴佸姩鐜� = (鏈堝害鍏ヨ亴鍛樺伐鏁� + 鏈堝害绂昏亴鍛樺伐鏁�) / 鏈堝垵鍛樺伐鏁� * 100%
+ Double flowRate = 0.0;
+ if (vo.getBeginMonthStaffCount() > 0) {
+ flowRate = (double) (vo.getNewHireCount() + vo.getLeaveCount()) / vo.getBeginMonthStaffCount() * 100;
+ // 淇濈暀涓や綅灏忔暟
+ flowRate = Math.round(flowRate * 100.0) / 100.0;
+ }
+ vo.setFlowRate(flowRate);
+
+ result.add(vo);
+ }
+
+ return result;
+ }
+
+ @Override
+ public TotalTurnoverRateVo getTotalStatistic() {
+ TotalTurnoverRateVo result = new TotalTurnoverRateVo();
+ LocalDate now = LocalDate.now();
+
+ // 鑾峰彇褰撳墠鍦ㄨ亴鍛樺伐鏁�
+ Integer currentOnJobCount = staffOnJobMapper.countOnJobStaffByDate(now);
+ result.setCurrentOnJobCount(currentOnJobCount);
+
+ // 鑾峰彇鏈湀鐨勫紑濮嬪拰缁撴潫鏃ユ湡
+ LocalDate monthStartDate = now.withDayOfMonth(1);
+ LocalDate monthEndDate = now.withDayOfMonth(now.lengthOfMonth());
+
+ // 鑾峰彇鏈堝垵鍛樺伐鏁帮紙鍗充笂鏈堟湯鍛樺伐鏁帮級
+ Integer beginMonthStaffCount = staffOnJobMapper.countOnJobStaffByDate(monthStartDate.minusDays(1));
+
+ // 鑾峰彇鏈湀鏂板叆鑱屽憳宸ユ暟
+ Integer newHireCount = staffOnJobMapper.countNewHireByMonth(monthStartDate, monthEndDate);
+
+ // 鑾峰彇鏈湀绂昏亴鍛樺伐鏁�
+ Integer leaveCount = staffLeaveMapper.countLeaveByMonth(monthStartDate, monthEndDate);
+
+ // 璁$畻鎬绘祦鍔ㄧ巼 = (鍏ヨ亴浜烘暟 + 绂昏亴浜烘暟) / 鏈堝垵鍛樺伐鏁� * 100%
+ Double totalFlowRate = 0.0;
+ if (beginMonthStaffCount > 0) {
+ totalFlowRate = (double) (newHireCount + leaveCount) / beginMonthStaffCount * 100;
+ // 淇濈暀涓や綅灏忔暟
+ totalFlowRate = Math.round(totalFlowRate * 100.0) / 100.0;
+ }
+ result.setTotalFlowRate(totalFlowRate);
+
+ // 璁$畻鎬绘祦澶辩巼 = 绂昏亴浜烘暟 / 鏈堝垵鍛樺伐鏁� * 100%
+ Double totalTurnoverRate = 0.0;
+ if (beginMonthStaffCount > 0) {
+ totalTurnoverRate = (double) leaveCount / beginMonthStaffCount * 100;
+ // 淇濈暀涓や綅灏忔暟
+ totalTurnoverRate = Math.round(totalTurnoverRate * 100.0) / 100.0;
+ }
+ result.setTotalTurnoverRate(totalTurnoverRate);
+
+ return result;
+ }
+}
diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
index 2d30dc5..ff8faa5 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
@@ -11,6 +11,7 @@
import com.ruoyi.staff.pojo.StaffOnJob;
import com.ruoyi.staff.service.StaffLeaveService;
import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.staff.pojo.StaffLeave;
import org.springframework.transaction.annotation.Transactional;
@@ -23,8 +24,10 @@
@AllArgsConstructor
@Service
public class StaffLeaveServiceImpl extends ServiceImpl<StaffLeaveMapper, StaffLeave> implements StaffLeaveService {
+ @Autowired
private StaffLeaveMapper staffLeaveMapper;
+ @Autowired
private StaffOnJobMapper staffOnJobMapper;
//鏂板绂昏亴鍒楄〃鍒嗛〉鏌ヨ
@@ -97,6 +100,5 @@
ExcelUtil<StaffLeaveDto> util = new ExcelUtil<StaffLeaveDto>(StaffLeaveDto.class);
util.exportExcel(response, staffLeaves, "鍛樺伐绂昏亴瀵煎嚭");
}
-
}
diff --git a/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java b/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
index 6fb0cd0..9756f33 100644
--- a/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
+++ b/src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -23,6 +23,7 @@
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@@ -39,12 +40,14 @@
@Service
public class StaffOnJobServiceImpl extends ServiceImpl<StaffOnJobMapper, StaffOnJob> implements IStaffOnJobService {
-
+ @Autowired
private StaffOnJobMapper staffOnJobMapper;
-
+ @Autowired
private SysPostMapper sysPostMapper;
+ @Autowired
private StaffContractMapper staffContractMapper;
+ @Autowired
private StaffLeaveMapper staffLeaveMapper;
diff --git a/src/main/java/com/ruoyi/staff/vo/MonthlyTurnoverRateVo.java b/src/main/java/com/ruoyi/staff/vo/MonthlyTurnoverRateVo.java
new file mode 100644
index 0000000..90f9c69
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/vo/MonthlyTurnoverRateVo.java
@@ -0,0 +1,39 @@
+package com.ruoyi.staff.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+/**
+ * 鏈堝害鍛樺伐娴佸姩鐜囧拰娴佸け鐜囩粺璁O
+ */
+@Data
+public class MonthlyTurnoverRateVo {
+ @ApiModelProperty("鏈堜唤")
+ private String month;
+
+ @ApiModelProperty("鏈堝垵鍛樺伐鏁�")
+ private Integer beginMonthStaffCount;
+
+ @ApiModelProperty("鏈堟湯鍛樺伐鏁�")
+ private Integer endMonthStaffCount;
+
+ @ApiModelProperty("鏈堝害鍏ヨ亴鍛樺伐鏁�")
+ private Integer newHireCount;
+
+ @ApiModelProperty("鏈堝害绂昏亴鍛樺伐鏁�")
+ private Integer leaveCount;
+
+ @ApiModelProperty("娴佸け鐜�(%)")
+ private Double turnoverRate;
+
+ @ApiModelProperty("娴佸姩鐜�(%)")
+ private Double flowRate;
+
+ @ApiModelProperty("鏈堜唤寮�濮嬫棩鏈�")
+ private LocalDate monthStartDate;
+
+ @ApiModelProperty("鏈堜唤缁撴潫鏃ユ湡")
+ private LocalDate monthEndDate;
+}
diff --git a/src/main/java/com/ruoyi/staff/vo/TotalTurnoverRateVo.java b/src/main/java/com/ruoyi/staff/vo/TotalTurnoverRateVo.java
new file mode 100644
index 0000000..49d2f42
--- /dev/null
+++ b/src/main/java/com/ruoyi/staff/vo/TotalTurnoverRateVo.java
@@ -0,0 +1,19 @@
+package com.ruoyi.staff.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 鍛樺伐鎬绘祦鍔ㄧ巼銆佹祦澶辩巼鍙婂湪鑱屽憳宸ユ暟缁熻VO
+ */
+@Data
+public class TotalTurnoverRateVo {
+ @ApiModelProperty("鎬绘祦鍔ㄧ巼(%)")
+ private Double totalFlowRate;
+
+ @ApiModelProperty("鎬绘祦澶辩巼(%)")
+ private Double totalTurnoverRate;
+
+ @ApiModelProperty("褰撳墠鍦ㄨ亴鍛樺伐鏁�")
+ private Integer currentOnJobCount;
+}
diff --git a/src/main/resources/mapper/production/ProductionProductMainMapper.xml b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
index 1d98782..11cd348 100644
--- a/src/main/resources/mapper/production/ProductionProductMainMapper.xml
+++ b/src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -48,6 +48,13 @@
order by ppm.id
</select>
+ <select id="getOrderByMainId" resultType="com.ruoyi.production.pojo.ProductOrder">
+ select po.*
+ from product_order po
+ left join product_work_order pwo on po.id = pwo.product_order_id
+ left join production_product_main pm on work_order_id=pwo.id
+ where pm.id=#{productMainId}
+ </select>
<delete id="deleteByWorkOrderIds" parameterType="java.util.List">
DELETE FROM production_product_main
diff --git a/src/main/resources/mapper/quality/QualityInspectMapper.xml b/src/main/resources/mapper/quality/QualityInspectMapper.xml
index 4e8a057..8058455 100644
--- a/src/main/resources/mapper/quality/QualityInspectMapper.xml
+++ b/src/main/resources/mapper/quality/QualityInspectMapper.xml
@@ -23,7 +23,7 @@
AND check_time >= DATE_FORMAT(#{qualityInspect.entryDateStart},'%Y-%m-%d')
</if>
<if test="qualityInspect.entryDateEnd != null and qualityInspect.entryDateEnd != '' ">
- AND check_time <= DATE_FORMAT(#{qualityInspect.entryDateEnd},'%Y-%m-%d')
+ AND check_time <= DATE_FORMAT(#{qualityInspect.entryDateEnd},'%Y-%m-%d')
</if>
ORDER BY check_time DESC
</select>
@@ -55,4 +55,292 @@
</foreach>
</delete>
+ <select id="getInspectStatistics" resultType="com.ruoyi.quality.dto.QualityInspectStatDto">
+ SELECT 0 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num) FROM procurement_record_storage WHERE type = 1), 0) +
+ COALESCE((SELECT SUM(quantity) FROM quality_unqualified WHERE inspect_type = 0), 0) AS totalCount,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 1
+ AND quality_inspect_id != 0
+ AND quality_inspect_id IS NOT NULL), 0) +
+ COALESCE((SELECT SUM(quantity) FROM quality_unqualified WHERE inspect_type = 0), 0) AS completedCount
+ UNION ALL
+ SELECT 1 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND sales_ledger_product_id = 0), 0) AS totalCount,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND sales_ledger_product_id = 0
+ AND quality_inspect_id != 0
+ AND quality_inspect_id IS NOT NULL), 0) AS completedCount
+ UNION ALL
+ SELECT 2 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND sales_ledger_product_id != 0), 0) AS totalCount,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND sales_ledger_product_id != 0
+ AND quality_inspect_id != 0
+ AND quality_inspect_id IS NOT NULL), 0) AS completedCount
+ </select>
+
+ <select id="getPassRateStatistics" resultType="com.ruoyi.quality.dto.QualityPassRateDto">
+ SELECT t.inspectType,
+ COALESCE(prs.totalCount, 0) AS totalCount,
+ COALESCE(qi.completedCount, 0) AS completedCount,
+ COALESCE(qi.qualifiedCount, 0) AS qualifiedCount,
+ COALESCE(qi.unqualifiedCount, 0) AS unqualifiedCount,
+ IF(COALESCE(prs.totalCount, 0) = 0, 0,
+ ROUND(COALESCE(qi.completedCount, 0) / prs.totalCount * 100, 2)) AS completionRate,
+ IF(COALESCE(qi.completedCount, 0) = 0, 0,
+ ROUND(COALESCE(qi.qualifiedCount, 0) / qi.completedCount * 100, 2)) AS passRate
+ FROM (SELECT 0 AS inspectType
+ UNION ALL
+ SELECT 1
+ UNION ALL
+ SELECT 2) t
+ LEFT JOIN (SELECT inspect_type,
+ SUM(quantity) AS completedCount,
+ SUM(IF(check_result = '鍚堟牸', quantity, 0)) AS qualifiedCount,
+ SUM(IF(check_result = '涓嶅悎鏍�', quantity, 0)) AS unqualifiedCount
+ FROM quality_inspect
+ WHERE inspect_state = 1
+ GROUP BY inspect_type) qi
+ ON t.inspectType = qi.inspect_type
+ LEFT JOIN (SELECT 0 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num) FROM procurement_record_storage WHERE type = 1),
+ 0) +
+ COALESCE((SELECT SUM(quantity) FROM quality_unqualified WHERE inspect_type = 0),
+ 0) AS totalCount
+ UNION ALL
+ SELECT 1 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND sales_ledger_product_id = 0), 0) AS totalCount
+ UNION ALL
+ SELECT 2 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND sales_ledger_product_id != 0), 0) AS totalCount) prs
+ ON t.inspectType = prs.inspectType
+ ORDER BY t.inspectType;
+ </select>
+
+ <select id="getMonthlyPassRateStatistics" resultType="com.ruoyi.quality.dto.QualityMonthlyPassRateDto">
+ WITH RECURSIVE
+ months AS (SELECT 1 AS month_num
+ UNION ALL
+ SELECT month_num + 1
+ FROM months
+ WHERE month_num < 12),
+ types AS (SELECT 0 AS inspectType
+ UNION ALL
+ SELECT 1
+ UNION ALL
+ SELECT 2),
+ base AS (SELECT m.month_num, t.inspectType
+ FROM months m,
+ types t),
+ qi_data AS (SELECT MONTH(check_time) AS month_num,
+ inspect_type,
+ SUM(quantity) AS completedCount,
+ SUM(CASE WHEN check_result = '鍚堟牸' THEN quantity ELSE 0 END) AS qualifiedCount,
+ SUM(CASE WHEN check_result = '涓嶅悎鏍�' THEN quantity ELSE 0 END) AS unqualifiedCount
+ FROM quality_inspect
+ WHERE YEAR(check_time) = #{year}
+ AND inspect_state = 1
+ GROUP BY MONTH(check_time), inspect_type),
+ prs_data AS (SELECT month_num,
+ inspectType,
+ SUM(totalCount) AS totalCount
+ FROM (SELECT MONTH(create_time) AS month_num,
+ 0 AS inspectType,
+ inbound_num AS totalCount
+ FROM procurement_record_storage
+ WHERE type = 1
+ AND YEAR(create_time) = #{year}
+ UNION ALL
+ SELECT MONTH(check_time) AS month_num,
+ 0 AS inspectType,
+ quantity AS totalCount
+ FROM quality_unqualified
+ WHERE inspect_type = 0
+ AND YEAR(check_time) = #{year}
+ UNION ALL
+ SELECT MONTH(create_time) AS month_num,
+ CASE
+ WHEN sales_ledger_product_id = 0 THEN 1
+ ELSE 2
+ END AS inspectType,
+ inbound_num AS totalCount
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND YEAR(create_time) = #{year}) sub
+ GROUP BY month_num, inspectType)
+ SELECT CASE b.month_num
+ WHEN 1 THEN '涓�鏈�'
+ WHEN 2 THEN '浜屾湀'
+ WHEN 3 THEN '涓夋湀'
+ WHEN 4 THEN '鍥涙湀'
+ WHEN 5 THEN '浜旀湀'
+ WHEN 6 THEN '鍏湀'
+ WHEN 7 THEN '涓冩湀'
+ WHEN 8 THEN '鍏湀'
+ WHEN 9 THEN '涔濇湀'
+ WHEN 10 THEN '鍗佹湀'
+ WHEN 11 THEN '鍗佷竴鏈�'
+ WHEN 12 THEN '鍗佷簩鏈�'
+ END AS month,
+ b.inspectType,
+ COALESCE(p.totalCount, 0) AS totalCount,
+ COALESCE(q.completedCount, 0) AS completedCount,
+ COALESCE(q.qualifiedCount, 0) AS qualifiedCount,
+ COALESCE(q.unqualifiedCount, 0) AS unqualifiedCount,
+ CASE
+ WHEN COALESCE(p.totalCount, 0) = 0 THEN 0
+ ELSE ROUND(COALESCE(q.completedCount, 0) / p.totalCount * 100, 2)
+ END AS completionRate,
+ CASE
+ WHEN COALESCE(q.completedCount, 0) = 0 THEN 0
+ ELSE ROUND(COALESCE(q.qualifiedCount, 0) / q.completedCount * 100, 2)
+ END AS passRate
+ FROM base b
+ LEFT JOIN qi_data q ON b.month_num = q.month_num AND b.inspectType = q.inspect_type
+ LEFT JOIN prs_data p ON b.month_num = p.month_num AND b.inspectType = p.inspectType
+ ORDER BY b.month_num, b.inspectType
+ </select>
+
+ <select id="getYearlyPassRateStatistics" resultType="com.ruoyi.quality.dto.QualityPassRateDto">
+ SELECT t.inspectType,
+ COALESCE(prs.totalCount, 0) AS totalCount,
+ COALESCE(qi.completedCount, 0) AS completedCount,
+ COALESCE(qi.qualifiedCount, 0) AS qualifiedCount,
+ COALESCE(qi.unqualifiedCount, 0) AS unqualifiedCount,
+ CASE
+ WHEN COALESCE(prs.totalCount, 0) = 0 THEN 0
+ ELSE ROUND(COALESCE(qi.completedCount, 0) / prs.totalCount * 100, 2)
+ END AS completionRate,
+ CASE
+ WHEN COALESCE(qi.completedCount, 0) = 0 THEN 0
+ ELSE ROUND(COALESCE(qi.qualifiedCount, 0) / qi.completedCount * 100, 2)
+ END AS passRate
+ FROM (SELECT 0 AS inspectType
+ UNION ALL
+ SELECT 1
+ UNION ALL
+ SELECT 2) t
+ LEFT JOIN (SELECT inspect_type,
+ SUM(quantity) AS completedCount,
+ SUM(CASE WHEN check_result = '鍚堟牸' THEN quantity ELSE 0 END) AS qualifiedCount,
+ SUM(CASE WHEN check_result = '涓嶅悎鏍�' THEN quantity ELSE 0 END) AS unqualifiedCount
+ FROM quality_inspect
+ WHERE YEAR(check_time) = #{year}
+ AND inspect_state = 1
+ GROUP BY inspect_type) qi
+ ON t.inspectType = qi.inspect_type
+ LEFT JOIN (SELECT 0 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 1
+ AND YEAR(create_time) = #{year}), 0) +
+ COALESCE((SELECT SUM(quantity)
+ FROM quality_unqualified
+ WHERE inspect_type = 0
+ AND YEAR(check_time) = #{year}), 0) AS totalCount
+ UNION ALL
+ SELECT 1 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND sales_ledger_product_id = 0
+ AND YEAR(create_time) = #{year}), 0) AS totalCount
+ UNION ALL
+ SELECT 2 AS inspectType,
+ COALESCE((SELECT SUM(inbound_num)
+ FROM procurement_record_storage
+ WHERE type = 2
+ AND sales_ledger_product_id != 0
+ AND YEAR(create_time) = #{year}), 0) AS totalCount) prs
+ ON t.inspectType = prs.inspectType
+ ORDER BY t.inspectType
+ </select>
+
+ <select id="getMonthlyCompletionDetails" resultType="com.ruoyi.quality.dto.QualityMonthlyDetailDto">
+ WITH RECURSIVE
+ months AS (SELECT 1 AS month_num
+ UNION ALL
+ SELECT month_num + 1
+ FROM months
+ WHERE month_num < 12),
+ qi_data AS (SELECT MONTH(check_time) AS month_num,
+ SUM(CASE WHEN inspect_type = 0 THEN quantity ELSE 0 END) AS rawMaterialCount,
+ SUM(CASE WHEN inspect_type = 1 THEN quantity ELSE 0 END) AS processCount,
+ SUM(CASE WHEN inspect_type = 2 THEN quantity ELSE 0 END) AS outgoingCount
+ FROM quality_inspect
+ WHERE YEAR(check_time) = #{year}
+ AND inspect_state = 1
+ GROUP BY MONTH(check_time))
+ SELECT CASE m.month_num
+ WHEN 1 THEN '涓�鏈�'
+ WHEN 2 THEN '浜屾湀'
+ WHEN 3 THEN '涓夋湀'
+ WHEN 4 THEN '鍥涙湀'
+ WHEN 5 THEN '浜旀湀'
+ WHEN 6 THEN '鍏湀'
+ WHEN 7 THEN '涓冩湀'
+ WHEN 8 THEN '鍏湀'
+ WHEN 9 THEN '涔濇湀'
+ WHEN 10 THEN '鍗佹湀'
+ WHEN 11 THEN '鍗佷竴鏈�'
+ WHEN 12 THEN '鍗佷簩鏈�'
+ END AS month,
+ COALESCE(d.rawMaterialCount, 0) AS rawMaterialCount,
+ COALESCE(d.processCount, 0) AS processCount,
+ COALESCE(d.outgoingCount, 0) AS outgoingCount
+ FROM months m
+ LEFT JOIN qi_data d ON m.month_num = d.month_num
+ ORDER BY m.month_num
+ </select>
+
+ <select id="getTopParameters" resultType="com.ruoyi.quality.dto.QualityParameterStatDto">
+ WITH parameter_counts AS (SELECT qip.parameter_item AS name,
+ SUM(COALESCE(qi.quantity, 0)) AS count
+ FROM quality_inspect qi
+ JOIN quality_inspect_param qip ON qip.inspect_id = qi.id
+ WHERE qi.inspect_type = #{inspectType}
+ GROUP BY qip.parameter_item),
+ ranked AS (SELECT name,
+ count,
+ ROW_NUMBER() OVER (ORDER BY count DESC) AS rn
+ FROM parameter_counts),
+ total AS (SELECT SUM(count) AS total_count
+ FROM parameter_counts)
+ SELECT name,
+ count,
+ CASE
+ WHEN (SELECT total_count FROM total) = 0 THEN 0
+ ELSE ROUND(count / (SELECT total_count FROM total) * 100, 2)
+ END AS percentage
+ FROM (SELECT name, count, rn
+ FROM ranked
+ WHERE rn <= 4
+ UNION ALL
+ SELECT '鍏朵粬妫�娴�' AS name,
+ SUM(count) AS count,
+ 5 AS rn
+ FROM ranked
+ WHERE rn > 4
+ HAVING SUM(count) > 0) t
+ ORDER BY rn
+ </select>
+
</mapper>
diff --git a/src/main/resources/mapper/quality/QualityTestStandardMapper.xml b/src/main/resources/mapper/quality/QualityTestStandardMapper.xml
index cd3fb66..b9ad8ed 100644
--- a/src/main/resources/mapper/quality/QualityTestStandardMapper.xml
+++ b/src/main/resources/mapper/quality/QualityTestStandardMapper.xml
@@ -30,5 +30,6 @@
<if test="process!='' and process!=null">
and pp.name = #{process}
</if>
+ order by qts.id desc
</select>
</mapper>
diff --git a/src/main/resources/mapper/staff/StaffLeaveMapper.xml b/src/main/resources/mapper/staff/StaffLeaveMapper.xml
index c3faf41..4637ff0 100644
--- a/src/main/resources/mapper/staff/StaffLeaveMapper.xml
+++ b/src/main/resources/mapper/staff/StaffLeaveMapper.xml
@@ -61,4 +61,24 @@
AND soj.staff_name LIKE CONCAT('%',#{c.staffName},'%')
</if>
</select>
+
+ <select id="staffLeaveReasonAnalytics" resultType="com.ruoyi.staff.dto.StaffLeaveDto">
+ SELECT
+ staff_leave.reason as reason,
+ COUNT(*) as count
+ FROM staff_leave
+ LEFT JOIN
+ staff_on_job soj ON soj.id = staff_leave.staff_on_job_id
+ where 1=1
+ GROUP BY staff_leave.reason
+ </select>
+
+ <!-- 缁熻鎸囧畾鏈堜唤鐨勭鑱屽憳宸ユ暟 -->
+ <select id="countLeaveByMonth" resultType="java.lang.Integer">
+ SELECT COUNT(*)
+ FROM staff_leave sl
+ LEFT JOIN staff_on_job soj ON sl.staff_on_job_id = soj.id
+ WHERE DATE_FORMAT(sl.create_time, '%Y-%m-%d') BETWEEN #{monthStart} AND #{monthEnd}
+ AND soj.staff_state = 0
+ </select>
</mapper>
diff --git a/src/main/resources/mapper/staff/StaffOnJobMapper.xml b/src/main/resources/mapper/staff/StaffOnJobMapper.xml
index a43bb37..75ae5ef 100644
--- a/src/main/resources/mapper/staff/StaffOnJobMapper.xml
+++ b/src/main/resources/mapper/staff/StaffOnJobMapper.xml
@@ -43,4 +43,19 @@
AND staff_name LIKE CONCAT('%',#{staffOnJob.staffName},'%')
</if>
</select>
+ <!-- 缁熻鎸囧畾鏃ユ湡鐨勫湪鑱屽憳宸ユ暟 -->
+ <select id="countOnJobStaffByDate" resultType="java.lang.Integer">
+ SELECT COUNT(*)
+ FROM staff_on_job
+ WHERE staff_state = 1
+ AND DATE_FORMAT(create_time, '%Y-%m-%d') <= #{date}
+ </select>
+
+ <!-- 缁熻鎸囧畾鏈堜唤鐨勬柊鍏ヨ亴鍛樺伐鏁� -->
+ <select id="countNewHireByMonth" resultType="java.lang.Integer">
+ SELECT COUNT(*)
+ FROM staff_on_job
+ WHERE staff_state = 1
+ AND DATE_FORMAT(create_time, '%Y-%m-%d') BETWEEN #{monthStart} AND #{monthEnd}
+ </select>
</mapper>
diff --git a/src/main/resources/mapper/system/SysDeptMapper.xml b/src/main/resources/mapper/system/SysDeptMapper.xml
index 5c6310a..afc1130 100644
--- a/src/main/resources/mapper/system/SysDeptMapper.xml
+++ b/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -20,32 +20,37 @@
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
+ <result property="staffCount" column="staff_count" />
</resultMap>
<sql id="selectDeptVo">
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time
from sys_dept d
</sql>
-
+
<select id="selectDeptList" parameterType="com.ruoyi.project.system.domain.SysDept" resultMap="SysDeptResult">
- <include refid="selectDeptVo"/>
- where d.del_flag = '0'
+ select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time,
+ count(distinct soj.id) as staff_count
+ from sys_dept d
+ left join staff_on_job soj on soj.sys_dept_id = d.dept_id and soj.staff_state = '1'
+ where d.del_flag = '0'
<if test="deptId != null and deptId != 0">
- AND dept_id = #{deptId}
+ AND d.dept_id = #{deptId}
</if>
- <if test="parentId != null and parentId != 0">
- AND parent_id = #{parentId}
+ <if test="parentId != null and parentId != 0">
+ AND d.parent_id = #{parentId}
</if>
<if test="deptName != null and deptName != ''">
- AND dept_name like concat('%', #{deptName}, '%')
+ AND d.dept_name like concat('%', #{deptName}, '%')
</if>
<if test="status != null and status != ''">
- AND status = #{status}
+ AND d.status = #{status}
</if>
<!-- 鏁版嵁鑼冨洿杩囨护 -->
${params.dataScope}
+ group by d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time
order by d.parent_id, d.order_num
- </select>
+ </select>
<select id="selectDeptListByRoleId" resultType="Long">
select d.dept_id
--
Gitblit v1.9.3