From f8ccc5ab312ab7c5d6c7eb7fac4e37924f513869 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期二, 03 十一月 2026 19:25:29 +0800
Subject: [PATCH] fix: 完善质量检验接口与质检员分配
---
doc/20261103_enable_process_maintenance_menu.sql | 56 +++++
src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java | 4
src/main/java/com/ruoyi/quality/mapper/QualityTestStandardMapper.java | 2
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java | 5
src/test/java/com/ruoyi/quality/controller/QualityInspectControllerTest.java | 29 ++
src/main/java/com/ruoyi/quality/service/IQualityTestStandardService.java | 2
src/main/java/com/ruoyi/quality/util/QualityInspectionValueValidator.java | 135 ++++++++++++
src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java | 3
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java | 60 +++++
src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java | 30 ++
src/test/java/com/ruoyi/quality/controller/QualityInspectParamControllerTest.java | 49 ++++
src/main/resources/mapper/quality/QualityTestStandardMapper.xml | 5
src/main/resources/mapper/system/SysUserMapper.xml | 19 +
src/main/resources/application-dev.yml | 223 ++++++++++++++++++++
src/main/java/com/ruoyi/quality/service/impl/QualityTestStandardServiceImpl.java | 4
doc/20261103_quality_inspect_user_assignment.sql | 5
src/main/resources/application-tide.yml | 5
17 files changed, 627 insertions(+), 9 deletions(-)
diff --git a/doc/20261103_enable_process_maintenance_menu.sql b/doc/20261103_enable_process_maintenance_menu.sql
new file mode 100644
index 0000000..f0a1566
--- /dev/null
+++ b/doc/20261103_enable_process_maintenance_menu.sql
@@ -0,0 +1,56 @@
+-- 鎭㈠鈥滃伐搴忕淮鎶も�濊彍鍗曪紙MySQL锛屽彲閲嶅鎵ц锛夈��
+-- 鑻ヤ緷绾﹀畾锛歷isible='0' 琛ㄧず鏄剧ず锛宻tatus='0' 琛ㄧず姝e父銆�
+
+-- 1. 鎭㈠鑿滃崟鏈韩锛屽苟淇鍓嶇缁勪欢鍦板潃銆�
+UPDATE sys_menu
+SET visible = '0',
+ status = '0',
+ menu_type = 'C',
+ component = 'productionManagement/productionProcess/index',
+ update_by = 'admin',
+ update_time = NOW()
+WHERE menu_name = '宸ュ簭缁存姢'
+ OR component = 'productionManagement/productionProcess/index';
+
+-- 2. 纭繚鐩存帴鐖惰彍鍗曞浜庢樉绀恒�佹甯哥姸鎬併��
+UPDATE sys_menu parent
+INNER JOIN sys_menu child ON child.parent_id = parent.menu_id
+SET parent.visible = '0',
+ parent.status = '0',
+ parent.update_by = 'admin',
+ parent.update_time = NOW()
+WHERE child.menu_name = '宸ュ簭缁存姢';
+
+-- 3. 缁欑鐞嗗憳瑙掕壊琛ラ綈鑿滃崟鍏崇郴锛堝凡瀛樺湪鏃朵笉閲嶅鎻掑叆锛夈��
+INSERT INTO sys_role_menu (role_id, menu_id)
+SELECT role.role_id, menu.menu_id
+FROM sys_role role
+INNER JOIN sys_menu menu ON menu.menu_name = '宸ュ簭缁存姢'
+WHERE role.role_key = 'admin'
+ AND NOT EXISTS (
+ SELECT 1
+ FROM sys_role_menu relation
+ WHERE relation.role_id = role.role_id
+ AND relation.menu_id = menu.menu_id
+ );
+
+-- 4. 鎵ц鍚庢鏌ヨ彍鍗曘�佺埗鑿滃崟鍜岃鑹叉巿鏉冪粨鏋溿��
+SELECT menu.menu_id,
+ menu.parent_id,
+ menu.menu_name,
+ menu.path,
+ menu.component,
+ menu.visible,
+ menu.status,
+ parent.menu_name AS parent_name,
+ parent.visible AS parent_visible,
+ parent.status AS parent_status
+FROM sys_menu menu
+LEFT JOIN sys_menu parent ON parent.menu_id = menu.parent_id
+WHERE menu.menu_name = '宸ュ簭缁存姢';
+
+SELECT role.role_name, role.role_key, relation.menu_id
+FROM sys_role_menu relation
+INNER JOIN sys_role role ON role.role_id = relation.role_id
+INNER JOIN sys_menu menu ON menu.menu_id = relation.menu_id
+WHERE menu.menu_name = '宸ュ簭缁存姢';
diff --git a/doc/20261103_quality_inspect_user_assignment.sql b/doc/20261103_quality_inspect_user_assignment.sql
new file mode 100644
index 0000000..ea0df51
--- /dev/null
+++ b/doc/20261103_quality_inspect_user_assignment.sql
@@ -0,0 +1,5 @@
+ALTER TABLE quality_inspect
+ ADD COLUMN check_user_id BIGINT NULL COMMENT '妫�楠屽憳绯荤粺鐢ㄦ埛ID' AFTER check_name;
+
+CREATE INDEX idx_quality_inspect_check_user_id
+ ON quality_inspect (check_user_id);
diff --git a/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java b/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
index 5507b3f..f9de981 100644
--- a/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
+++ b/src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
@@ -27,6 +27,9 @@
*/
public List<SysUser> selectUserList(SysUser sysUser);
+ /** 褰撳墠绉熸埛涓彲鐢ㄤ簬涓氬姟鍒嗛厤鐨勬甯哥郴缁熺敤鎴枫�� */
+ public List<SysUser> selectActiveUsers(@Param("tenantId") Long tenantId);
+
/**
* 鏍规嵁鏉′欢鍒嗛〉鏌ヨ宸查厤鐢ㄦ埛瑙掕壊鍒楄〃
*
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityInspectController.java b/src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
index 1702c2a..3d9a177 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
@@ -2,7 +2,11 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.project.system.domain.SysUser;
+import com.ruoyi.project.system.mapper.SysUserMapper;
+import com.ruoyi.project.system.service.ISysUserService;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.procurementrecord.service.impl.ProcurementRecordServiceImpl;
@@ -15,6 +19,7 @@
import com.ruoyi.quality.service.IQualityInspectParamService;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.quality.service.IQualityUnqualifiedService;
+import com.ruoyi.quality.util.QualityInspectionValueValidator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
@@ -23,6 +28,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
+import java.util.Objects;
/**
* 鍘熸潗鏂欐楠�/杩囩▼妫�楠�/鍑哄巶妫�楠�
@@ -41,6 +47,12 @@
private IQualityInspectFileService qualityInspectFileService;
@Autowired
private ProcurementRecordService procurementRecordService;
+
+ @Resource
+ private ISysUserService sysUserService;
+
+ @Resource
+ private SysUserMapper sysUserMapper;
/**
@@ -108,6 +120,48 @@
return AjaxResult.error("宸叉彁浜ょ殑妫�楠岃褰曚笉鑳戒慨鏀�");
}
return AjaxResult.success(qualityInspectService.updateQualityInspect(qualityInspectDto));
+ }
+
+ /** 浠呭垎閰嶆楠屽憳锛岄伩鍏嶈Е鍙戞暣寮犳楠屽崟鐨勫繀濉牎楠屻�� */
+ @PostMapping("/assignInspector")
+ public AjaxResult assignInspector(@RequestBody QualityInspect inspect) {
+ if (inspect == null || inspect.getId() == null) {
+ return AjaxResult.error("妫�楠岃褰旾D涓嶈兘涓虹┖");
+ }
+ if (inspect.getCheckUserId() == null) {
+ return AjaxResult.error("璇烽�夋嫨妫�楠屽憳");
+ }
+ QualityInspect stored = qualityInspectService.getById(inspect.getId());
+ if (stored == null) {
+ return AjaxResult.error("妫�楠岃褰曚笉瀛樺湪");
+ }
+ if (Integer.valueOf(1).equals(stored.getInspectState())) {
+ return AjaxResult.error("宸叉彁浜ょ殑妫�楠岃褰曚笉鑳介噸鏂板垎閰嶆楠屽憳");
+ }
+ SysUser inspector = sysUserService.selectUserById(inspect.getCheckUserId());
+ if (inspector == null || "2".equals(inspector.getDelFlag())) {
+ return AjaxResult.error("鎵�閫夌敤鎴蜂笉瀛樺湪鎴栧凡鍒犻櫎");
+ }
+ if (!SecurityUtils.isAdmin(SecurityUtils.getUserId())
+ && !Objects.equals(SecurityUtils.getLoginUser().getTenantId(), inspector.getTenantId())) {
+ return AjaxResult.error("鍙兘鍒嗛厤缁欏綋鍓嶅叕鍙哥敤鎴�");
+ }
+ if (!"0".equals(inspector.getStatus())) {
+ return AjaxResult.error("鎵�閫夌敤鎴峰凡鍋滅敤");
+ }
+ QualityInspect update = new QualityInspect();
+ update.setId(inspect.getId());
+ update.setCheckUserId(inspector.getUserId());
+ update.setCheckName(StringUtils.defaultIfBlank(inspector.getNickName(), inspector.getUserName()));
+ return AjaxResult.success(qualityInspectService.updateById(update));
+ }
+
+ /** 浠呰繑鍥炲綋鍓嶇鎴蜂腑姝e父銆佹湭鍒犻櫎鐨勭郴缁熺敤鎴凤紝渚涜川妫�鍛樺垎閰嶄娇鐢ㄣ�� */
+ @GetMapping("/inspectorCandidates")
+ public AjaxResult inspectorCandidates() {
+ Long tenantId = SecurityUtils.isAdmin(SecurityUtils.getUserId())
+ ? null : SecurityUtils.getLoginUser().getTenantId();
+ return AjaxResult.success(sysUserMapper.selectActiveUsers(tenantId));
}
/**
@@ -187,6 +241,12 @@
return "璇峰~鍐欌��" + parameter.getParameterItem() + "鈥濈殑妫�楠屽��";
}
}
+ if ("鍚堟牸".equals(inspect.getCheckResult())) {
+ String valueMessage = QualityInspectionValueValidator.validateQualified(inspect.getQualityInspectParams());
+ if (valueMessage != null) {
+ return valueMessage;
+ }
+ }
return null;
}
}
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java b/src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java
index 3d6df0c..78fb8ee 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityInspectParamController.java
@@ -9,6 +9,8 @@
import com.ruoyi.quality.service.IQualityInspectFileService;
import com.ruoyi.quality.service.IQualityInspectParamService;
import com.ruoyi.quality.service.IQualityInspectService;
+import com.ruoyi.quality.util.QualityInspectionValueValidator;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -25,6 +27,9 @@
@Resource
private IQualityInspectParamService qualityInspectParamService;
+
+ @Resource
+ private IQualityInspectService qualityInspectService;
/**
* 璇︽儏
@@ -44,6 +49,31 @@
*/
@PostMapping("/update")
public AjaxResult update(@RequestBody List<QualityInspectParam> qualityInspectParams) {
+ if (CollectionUtils.isEmpty(qualityInspectParams)) {
+ return AjaxResult.error("妫�楠岄」鐩笉鑳戒负绌�");
+ }
+ Long inspectId = qualityInspectParams.get(0).getInspectId();
+ if (inspectId == null) {
+ return AjaxResult.error("妫�楠岃褰旾D涓嶈兘涓虹┖");
+ }
+ QualityInspect inspect = qualityInspectService.getById(inspectId);
+ if (inspect == null) {
+ return AjaxResult.error("妫�楠岃褰曚笉瀛樺湪");
+ }
+ if (Integer.valueOf(1).equals(inspect.getInspectState())) {
+ return AjaxResult.error("宸叉彁浜ょ殑妫�楠岃褰曚笉鑳戒慨鏀�");
+ }
+ for (QualityInspectParam parameter : qualityInspectParams) {
+ if (StringUtils.isBlank(parameter.getTestValue())) {
+ return AjaxResult.error("璇峰~鍐欌��" + parameter.getParameterItem() + "鈥濈殑妫�楠屽��");
+ }
+ }
+ if ("鍚堟牸".equals(inspect.getCheckResult())) {
+ String valueMessage = QualityInspectionValueValidator.validateQualified(qualityInspectParams);
+ if (valueMessage != null) {
+ return AjaxResult.error(valueMessage);
+ }
+ }
return AjaxResult.success(qualityInspectParamService.updateBatchById(qualityInspectParams));
}
diff --git a/src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java b/src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java
index c018bce..32f0489 100644
--- a/src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java
+++ b/src/main/java/com/ruoyi/quality/controller/QualityTestStandardController.java
@@ -101,8 +101,8 @@
* @return
*/
@GetMapping("/getQualityTestStandardByProductId")
- public AjaxResult getQualityTestStandardByProductId(@Nonnull Long productId, @Nonnull Integer inspectType, String process) {
- return AjaxResult.success(qualityTestStandardService.getQualityTestStandardByProductId(productId,inspectType,process));
+ public AjaxResult getQualityTestStandardByProductId(@Nonnull Long productId, @Nonnull Integer inspectType, Long processId) {
+ return AjaxResult.success(qualityTestStandardService.getQualityTestStandardByProductId(productId, inspectType, processId));
}
/**
diff --git a/src/main/java/com/ruoyi/quality/mapper/QualityTestStandardMapper.java b/src/main/java/com/ruoyi/quality/mapper/QualityTestStandardMapper.java
index a394b86..01ddb7a 100644
--- a/src/main/java/com/ruoyi/quality/mapper/QualityTestStandardMapper.java
+++ b/src/main/java/com/ruoyi/quality/mapper/QualityTestStandardMapper.java
@@ -22,7 +22,7 @@
IPage<QualityTestStandard> qualityTestStandardListPage(Page page, @Param("c") QualityTestStandard qualityTestStandard);
- List<QualityTestStandard> getQualityTestStandardByProductId(@Param("productId") Long productId, @Param("inspectType") Integer inspectType, @Param("process") String process);
+ List<QualityTestStandard> getQualityTestStandardByProductId(@Param("productId") Long productId, @Param("inspectType") Integer inspectType, @Param("processId") Long processId);
}
diff --git a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
index 5216cd6..2b86d71 100644
--- a/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
+++ b/src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -70,6 +70,11 @@
private String checkName;
/**
+ * 妫�楠屽憳瀵瑰簲鐨勭郴缁熺敤鎴稩D
+ */
+ private Long checkUserId;
+
+ /**
* 鍏宠仈浜у搧id
*/
@NotBlank(message = "浜у搧id涓嶈兘涓虹┖")
diff --git a/src/main/java/com/ruoyi/quality/service/IQualityTestStandardService.java b/src/main/java/com/ruoyi/quality/service/IQualityTestStandardService.java
index a580765..ac2fbaa 100644
--- a/src/main/java/com/ruoyi/quality/service/IQualityTestStandardService.java
+++ b/src/main/java/com/ruoyi/quality/service/IQualityTestStandardService.java
@@ -21,6 +21,6 @@
int copyParam(QualityTestStandard qualityTestStandard);
- List<QualityTestStandard> getQualityTestStandardByProductId(Long productId, Integer inspectType, String process);
+ List<QualityTestStandard> getQualityTestStandardByProductId(Long productId, Integer inspectType, Long processId);
}
diff --git a/src/main/java/com/ruoyi/quality/service/impl/QualityTestStandardServiceImpl.java b/src/main/java/com/ruoyi/quality/service/impl/QualityTestStandardServiceImpl.java
index 339a10d..431736b 100644
--- a/src/main/java/com/ruoyi/quality/service/impl/QualityTestStandardServiceImpl.java
+++ b/src/main/java/com/ruoyi/quality/service/impl/QualityTestStandardServiceImpl.java
@@ -60,8 +60,8 @@
}
@Override
- public List<QualityTestStandard> getQualityTestStandardByProductId(Long productId, Integer inspectType, String process) {
- return qualityTestStandardMapper.getQualityTestStandardByProductId(productId, inspectType, process);
+ public List<QualityTestStandard> getQualityTestStandardByProductId(Long productId, Integer inspectType, Long processId) {
+ return qualityTestStandardMapper.getQualityTestStandardByProductId(productId, inspectType, processId);
}
diff --git a/src/main/java/com/ruoyi/quality/util/QualityInspectionValueValidator.java b/src/main/java/com/ruoyi/quality/util/QualityInspectionValueValidator.java
new file mode 100644
index 0000000..8d3f8f5
--- /dev/null
+++ b/src/main/java/com/ruoyi/quality/util/QualityInspectionValueValidator.java
@@ -0,0 +1,135 @@
+package com.ruoyi.quality.util;
+
+import com.ruoyi.quality.pojo.QualityInspectParam;
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 妫�楠屽�间笌鏍囧噯/鍐呮帶鑼冨洿鏍¢獙銆�
+ * 鏀寔鍖洪棿銆佹璐熷亸宸�佸ぇ灏忔瘮杈冨拰绮剧‘鏁板�硷紝渚嬪锛�1.95~2.05銆�2.00卤0.10銆佲墹0.02銆佲墺100銆�
+ */
+public final class QualityInspectionValueValidator {
+
+ private static final String NUMBER = "(-?\\d+(?:\\.\\d+)?)";
+ private static final Pattern RANGE = Pattern.compile("^" + NUMBER + "(?:~|锝瀨鑷硘鈥攟-)" + NUMBER + "$");
+ private static final Pattern PLUS_MINUS = Pattern.compile("^" + NUMBER + "(?:卤|\\+/-)" + NUMBER + "$");
+ private static final Pattern TOLERANCE_ONLY = Pattern.compile("^(?:卤|\\+/-)" + NUMBER + "$");
+ private static final Pattern COMPARE = Pattern.compile("^(<=|>=|<|>|鈮鈮�)" + NUMBER + "$");
+ private static final Pattern EXACT = Pattern.compile("^" + NUMBER + "$");
+ private static final Pattern OBVIOUS_ABNORMAL_TEXT = Pattern.compile(".*(寮傚父|涓嶅悎鏍紎澶辫触|涓嶉�氳繃|瓒呮爣|缂洪櫡).*", Pattern.CASE_INSENSITIVE);
+
+ private QualityInspectionValueValidator() {
+ }
+
+ public static String validateQualified(List<QualityInspectParam> parameters) {
+ if (parameters == null) {
+ return null;
+ }
+ for (QualityInspectParam parameter : parameters) {
+ String message = validateParameter(parameter);
+ if (message != null) {
+ return message;
+ }
+ }
+ return null;
+ }
+
+ private static String validateParameter(QualityInspectParam parameter) {
+ if (parameter == null || StringUtils.isBlank(parameter.getTestValue())) {
+ return null;
+ }
+ String testText = normalize(parameter.getTestValue());
+ if (OBVIOUS_ABNORMAL_TEXT.matcher(testText).matches()) {
+ return error(parameter, effectiveRule(parameter));
+ }
+
+ BigDecimal testValue = decimal(testText);
+ String rule = firstNumericRule(parameter.getControlValue(), parameter.getStandardValue());
+ if (rule == null) {
+ return null;
+ }
+ if (testValue == null || !matches(testValue, rule)) {
+ return error(parameter, rule);
+ }
+ return null;
+ }
+
+ private static String firstNumericRule(String controlValue, String standardValue) {
+ String control = normalize(controlValue);
+ if (isSupportedRule(control)) {
+ return control;
+ }
+ String standard = normalize(standardValue);
+ return isSupportedRule(standard) ? standard : null;
+ }
+
+ private static boolean isSupportedRule(String rule) {
+ return rule != null && (RANGE.matcher(rule).matches()
+ || PLUS_MINUS.matcher(rule).matches()
+ || TOLERANCE_ONLY.matcher(rule).matches()
+ || COMPARE.matcher(rule).matches()
+ || EXACT.matcher(rule).matches());
+ }
+
+ private static boolean matches(BigDecimal value, String rule) {
+ Matcher matcher = RANGE.matcher(rule);
+ if (matcher.matches()) {
+ BigDecimal first = new BigDecimal(matcher.group(1));
+ BigDecimal second = new BigDecimal(matcher.group(2));
+ BigDecimal min = first.min(second);
+ BigDecimal max = first.max(second);
+ return value.compareTo(min) >= 0 && value.compareTo(max) <= 0;
+ }
+ matcher = PLUS_MINUS.matcher(rule);
+ if (matcher.matches()) {
+ BigDecimal center = new BigDecimal(matcher.group(1));
+ BigDecimal tolerance = new BigDecimal(matcher.group(2)).abs();
+ return value.compareTo(center.subtract(tolerance)) >= 0
+ && value.compareTo(center.add(tolerance)) <= 0;
+ }
+ Matcher toleranceOnly = TOLERANCE_ONLY.matcher(rule);
+ if (toleranceOnly.matches()) {
+ BigDecimal tolerance = new BigDecimal(toleranceOnly.group(1)).abs();
+ return value.abs().compareTo(tolerance) <= 0;
+ }
+ matcher = COMPARE.matcher(rule);
+ if (matcher.matches()) {
+ int compared = value.compareTo(new BigDecimal(matcher.group(2)));
+ String operator = matcher.group(1);
+ if ("<".equals(operator)) return compared < 0;
+ if (">".equals(operator)) return compared > 0;
+ if ("<=".equals(operator) || "鈮�".equals(operator)) return compared <= 0;
+ return compared >= 0;
+ }
+ matcher = EXACT.matcher(rule);
+ return matcher.matches() && value.compareTo(new BigDecimal(matcher.group(1))) == 0;
+ }
+
+ private static BigDecimal decimal(String value) {
+ try {
+ return StringUtils.isBlank(value) ? null : new BigDecimal(value);
+ } catch (NumberFormatException ignored) {
+ return null;
+ }
+ }
+
+ private static String normalize(String value) {
+ return StringUtils.isBlank(value) ? null : value.trim().replaceAll("\\s+", "").replace(",", "");
+ }
+
+ private static String effectiveRule(QualityInspectParam parameter) {
+ return StringUtils.isNotBlank(parameter.getControlValue())
+ ? parameter.getControlValue() : parameter.getStandardValue();
+ }
+
+ private static String error(QualityInspectParam parameter, String rule) {
+ String item = StringUtils.defaultIfBlank(parameter.getParameterItem(), "鏈懡鍚嶆寚鏍�");
+ String standard = StringUtils.defaultIfBlank(rule, "宸查厤缃爣鍑�");
+ return "妫�楠岄」鐩��" + item + "鈥濈殑妫�楠屽�尖��" + parameter.getTestValue()
+ + "鈥濅笉绗﹀悎鏍囧噯锛�" + standard + "锛夛紝涓嶈兘鎸夊悎鏍间繚瀛�";
+ }
+}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..99f6727
--- /dev/null
+++ b/src/main/resources/application-dev.yml
@@ -0,0 +1,223 @@
+# 鑺-浠撳偍鐗╂祦绯荤粺椤圭洰鐩稿叧閰嶇疆
+inspur:
+ appId: 1211004787244400640
+ appSecret: qZw3MjAwMTIwMjYxNTAxNDYyOTEy0U
+ruoyi:
+ # 鍚嶇О
+ name: RuoYi
+ # 鐗堟湰
+ version: 3.8.9
+ # 鐗堟潈骞翠唤
+ copyrightYear: 2025
+ # 鏂囦欢璺緞 绀轰緥锛� Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛�
+ profile: /center-lims/mis/file
+
+ # 鑾峰彇ip鍦板潃寮�鍏�
+ addressEnabled: false
+ # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
+ captchaType: math
+
+# 寮�鍙戠幆澧冮厤缃�
+server:
+ # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
+ port: 8034
+ servlet:
+ # 搴旂敤鐨勮闂矾寰�
+ context-path: /
+ tomcat:
+ # tomcat鐨刄RI缂栫爜
+ uri-encoding: UTF-8
+ # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓�100
+ accept-count: 1000
+ threads:
+ # tomcat鏈�澶х嚎绋嬫暟锛岄粯璁や负200
+ max: 800
+ # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊�10
+ min-spare: 100
+
+# 鏃ュ織閰嶇疆
+logging:
+ level:
+ com.ruoyi: warn
+ org.springframework: warn
+
+minio:
+ endpoint: http://114.132.189.42/
+ port: 7019
+ secure: false
+ accessKey: admin
+ secretKey: 12345678
+ preview-expiry: 24 # 棰勮鍦板潃榛樿24灏忔椂
+ default-bucket: uploadPath
+# 鐢ㄦ埛閰嶇疆
+user:
+ password:
+ # 瀵嗙爜鏈�澶ч敊璇鏁�
+ maxRetryCount: 5
+ # 瀵嗙爜閿佸畾鏃堕棿锛堥粯璁�10鍒嗛挓锛�
+ lockTime: 10
+
+# Spring閰嶇疆
+spring:
+ datasource:
+ type: com.alibaba.druid.pool.DruidDataSource
+ driverClassName: com.mysql.cj.jdbc.Driver
+ druid:
+ # 涓诲簱鏁版嵁婧�
+ master:
+ url: jdbc:mysql://10.136.65.135:3306/zlglxt-ruoyi-xinlan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+ username: root
+ password: zttZTT123!
+ # 浠庡簱鏁版嵁婧�
+ slave:
+ # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
+ enabled: false
+ url:
+ username:
+ password:
+ # 鍒濆杩炴帴鏁�
+ initialSize: 5
+ # 鏈�灏忚繛鎺ユ睜鏁伴噺
+ minIdle: 10
+ # 鏈�澶ц繛鎺ユ睜鏁伴噺
+ maxActive: 20
+ # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
+ maxWait: 60000
+ # 閰嶇疆杩炴帴瓒呮椂鏃堕棿
+ connectTimeout: 30000
+ # 閰嶇疆缃戠粶瓒呮椂鏃堕棿
+ socketTimeout: 60000
+ # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
+ timeBetweenEvictionRunsMillis: 60000
+ # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+ minEvictableIdleTimeMillis: 300000
+ # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣
+ maxEvictableIdleTimeMillis: 900000
+ # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+ validationQuery: SELECT 1 FROM DUAL
+ testWhileIdle: true
+ testOnBorrow: false
+ testOnReturn: false
+ webStatFilter:
+ enabled: true
+ statViewServlet:
+ enabled: true
+ # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+ allow:
+ url-pattern: /druid/*
+ # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+ login-username: ruoyi
+ login-password: 123456
+ filter:
+ stat:
+ enabled: true
+ # 鎱QL璁板綍
+ log-slow-sql: true
+ slow-sql-millis: 1000
+ merge-sql: true
+ wall:
+ config:
+ multi-statement-allow: true
+ # 璧勬簮淇℃伅
+ messages:
+ # 鍥介檯鍖栬祫婧愭枃浠惰矾寰�
+ basename: i18n/messages
+ # 鏂囦欢涓婁紶
+ servlet:
+ multipart:
+ # 鍗曚釜鏂囦欢澶у皬
+ max-file-size: 1GB
+ # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬
+ max-request-size: 2GB
+ # 鏈嶅姟妯″潡
+ devtools:
+ restart:
+ # 鐑儴缃插紑鍏�
+ enabled: false
+ # redis 閰嶇疆
+ redis:
+ # 鍦板潃
+ # host: 127.0.0.1
+ host: 10.136.65.135
+ # 绔彛锛岄粯璁や负6379
+ port: 6379
+ # 鏁版嵁搴撶储寮�
+ database: 0
+ # 瀵嗙爜
+ password: zttZTT123!
+ # password: 123456
+
+ # 杩炴帴瓒呮椂鏃堕棿
+ timeout: 10s
+ lettuce:
+ pool:
+ # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+ min-idle: 0
+ # 杩炴帴姹犱腑鐨勬渶澶х┖闂茶繛鎺�
+ max-idle: 8
+ # 杩炴帴姹犵殑鏈�澶ф暟鎹簱杩炴帴鏁�
+ max-active: 8
+ # #杩炴帴姹犳渶澶ч樆濉炵瓑寰呮椂闂达紙浣跨敤璐熷�艰〃绀烘病鏈夐檺鍒讹級
+ max-wait: -1ms
+
+# token閰嶇疆
+token:
+ # 浠ょ墝鑷畾涔夋爣璇�
+ header: Authorization
+ # 浠ょ墝瀵嗛挜
+ secret: abcdefghijklmnopqrstuvwxyz
+ # 浠ょ墝鏈夋晥鏈燂紙榛樿30鍒嗛挓锛�
+ expireTime: 450
+
+# MyBatis Plus閰嶇疆
+mybatis-plus:
+ # 鎼滅储鎸囧畾鍖呭埆鍚� 鏍规嵁鑷繁鐨勯」鐩潵
+ typeAliasesPackage: com.ruoyi.**.pojo
+ # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵�鏈夌殑mapper.xml鏄犲皠鏂囦欢
+ mapperLocations: classpath*:mapper/**/*Mapper.xml
+ # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠�
+ configLocation: classpath:mybatis/mybatis-config.xml
+ global-config:
+ enable-sql-runner: true
+ db-config:
+ id-type: auto
+
+# PageHelper鍒嗛〉鎻掍欢
+pagehelper:
+ helperDialect: mysql
+ supportMethodsArguments: true
+ params: count=countSql
+
+# Swagger閰嶇疆
+swagger:
+ # 鏄惁寮�鍚痵wagger
+ enabled: false
+ # 璇锋眰鍓嶇紑
+ pathMapping: /dev-api
+
+# 闃叉XSS鏀诲嚮
+xss:
+ # 杩囨护寮�鍏�
+ enabled: true
+ # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛�
+ excludes: /system/notice
+ # 鍖归厤閾炬帴
+ urlPatterns: /system/*,/monitor/*,/tool/*
+
+# 浠g爜鐢熸垚
+gen:
+ # 浣滆��
+ author: ruoyi
+ # 榛樿鐢熸垚鍖呰矾寰� system 闇�鏀规垚鑷繁鐨勬ā鍧楀悕绉� 濡� system monitor tool
+ packageName: com.ruoyi.project.system
+ # 鑷姩鍘婚櫎琛ㄥ墠缂�锛岄粯璁ゆ槸true
+ autoRemovePre: false
+ # 琛ㄥ墠缂�锛堢敓鎴愮被鍚嶄笉浼氬寘鍚〃鍓嶇紑锛屽涓敤閫楀彿鍒嗛殧锛�
+ tablePrefix: sys_
+ # 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
+ allowOverwrite: false
+
+# 鏈湴寮�鍙戞枃浠剁洰褰�
+file:
+ temp-dir: "L:/20260813xxinruan/浜岀骇椤圭洰娴疆寮�鍙�/璐ㄩ噺绠$悊妫�娴嬬郴缁�/.tmp/uploads/temp"
+ upload-dir: "L:/20260813xxinruan/浜岀骇椤圭洰娴疆寮�鍙�/璐ㄩ噺绠$悊妫�娴嬬郴缁�/.tmp/uploads/files"
diff --git a/src/main/resources/application-tide.yml b/src/main/resources/application-tide.yml
index fc862e8..48013c5 100644
--- a/src/main/resources/application-tide.yml
+++ b/src/main/resources/application-tide.yml
@@ -216,3 +216,8 @@
tablePrefix: sys_
# 鏄惁鍏佽鐢熸垚鏂囦欢瑕嗙洊鍒版湰鍦帮紙鑷畾涔夎矾寰勶級锛岄粯璁や笉鍏佽
allowOverwrite: false
+
+# 鏈湴寮�鍙戞枃浠剁洰褰�
+file:
+ temp-dir: "L:/20260813xxinruan/浜岀骇椤圭洰娴疆寮�鍙�/璐ㄩ噺绠$悊妫�娴嬬郴缁�/.tmp/uploads/temp"
+ upload-dir: "L:/20260813xxinruan/浜岀骇椤圭洰娴疆寮�鍙�/璐ㄩ噺绠$悊妫�娴嬬郴缁�/.tmp/uploads/files"
diff --git a/src/main/resources/mapper/quality/QualityTestStandardMapper.xml b/src/main/resources/mapper/quality/QualityTestStandardMapper.xml
index a17ac3e..16d4ffd 100644
--- a/src/main/resources/mapper/quality/QualityTestStandardMapper.xml
+++ b/src/main/resources/mapper/quality/QualityTestStandardMapper.xml
@@ -24,11 +24,10 @@
SELECT qts.*
FROM quality_test_standard qts
left join quality_test_standard_binding qtsb on qtsb.test_standard_id = qts.id
- left join product_process pp on qts.process_id = pp.id
WHERE qtsb.product_id = #{productId}
AND qts.inspect_type = #{inspectType}
- <if test="process!='' and process!=null">
- and pp.name = #{process}
+ <if test="processId != null">
+ and qts.process_id = #{processId}
</if>
order by qts.id desc
</select>
diff --git a/src/main/resources/mapper/system/SysUserMapper.xml b/src/main/resources/mapper/system/SysUserMapper.xml
index 5ac9a4d..6ffc9de 100644
--- a/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/src/main/resources/mapper/system/SysUserMapper.xml
@@ -98,6 +98,25 @@
${params.dataScope}
</select>
+ <select id="selectActiveUsers" resultMap="SysUserResult">
+ SELECT u.user_id,
+ u.user_name,
+ COALESCE(NULLIF(u.nick_name, ''), u.user_name) AS nick_name,
+ u.status,
+ u.tenant_id,
+ GROUP_CONCAT(DISTINCT d.dept_name ORDER BY d.dept_name SEPARATOR ', ') AS dept_names
+ FROM sys_user u
+ LEFT JOIN sys_user_dept ud ON ud.user_id = u.user_id
+ LEFT JOIN sys_dept d ON d.dept_id = ud.dept_id
+ WHERE u.status = '0'
+ AND u.del_flag = '0'
+ <if test="tenantId != null">
+ AND u.tenant_id = #{tenantId}
+ </if>
+ GROUP BY u.user_id, u.user_name, u.nick_name, u.status, u.tenant_id
+ ORDER BY nick_name, u.user_name
+ </select>
+
<select id="selectAllocatedList" parameterType="com.ruoyi.project.system.domain.SysUser" resultMap="SysUserResult">
select distinct u.user_id, u.user_name, u.nick_name, u.email, u.phonenumber, u.status, u.create_time
from sys_user u
diff --git a/src/test/java/com/ruoyi/quality/controller/QualityInspectControllerTest.java b/src/test/java/com/ruoyi/quality/controller/QualityInspectControllerTest.java
index 9b781b4..5b34a72 100644
--- a/src/test/java/com/ruoyi/quality/controller/QualityInspectControllerTest.java
+++ b/src/test/java/com/ruoyi/quality/controller/QualityInspectControllerTest.java
@@ -70,6 +70,35 @@
}
@Test
+ void addRejectsOutOfRangeValueWhenMarkedQualified() {
+ QualityInspectDto dto = validInspection(0);
+ dto.getQualityInspectParams().get(0).setTestValue("80");
+
+ AjaxResult result = controller.add(dto);
+
+ assertTrue(result.isError());
+ assertTrue(String.valueOf(result.get(AjaxResult.MSG_TAG)).contains("涓嶈兘鎸夊悎鏍间繚瀛�"));
+ verify(inspectService, never()).add(any());
+ }
+
+ @Test
+ void assignInspectorOnlyUpdatesInspectorField() {
+ QualityInspect request = new QualityInspect();
+ request.setId(9L);
+ request.setCheckName("寮犳楠�");
+ QualityInspect stored = new QualityInspect();
+ stored.setId(9L);
+ stored.setInspectState(0);
+ when(inspectService.getById(9L)).thenReturn(stored);
+ when(inspectService.updateById(any(QualityInspect.class))).thenReturn(true);
+
+ AjaxResult result = controller.assignInspector(request);
+
+ assertTrue(result.isSuccess());
+ verify(inspectService).updateById(any(QualityInspect.class));
+ }
+
+ @Test
void processInspectionRequiresProcess() {
QualityInspectDto dto = validInspection(1);
dto.setProcess(null);
diff --git a/src/test/java/com/ruoyi/quality/controller/QualityInspectParamControllerTest.java b/src/test/java/com/ruoyi/quality/controller/QualityInspectParamControllerTest.java
new file mode 100644
index 0000000..09e36e1
--- /dev/null
+++ b/src/test/java/com/ruoyi/quality/controller/QualityInspectParamControllerTest.java
@@ -0,0 +1,49 @@
+package com.ruoyi.quality.controller;
+
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.quality.pojo.QualityInspect;
+import com.ruoyi.quality.pojo.QualityInspectParam;
+import com.ruoyi.quality.service.IQualityInspectParamService;
+import com.ruoyi.quality.service.IQualityInspectService;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class QualityInspectParamControllerTest {
+
+ @Mock private IQualityInspectParamService paramService;
+ @Mock private IQualityInspectService inspectService;
+ @InjectMocks private QualityInspectParamController controller;
+
+ @Test
+ void updateRejectsOutOfRangeValueForQualifiedInspection() {
+ QualityInspect inspect = new QualityInspect();
+ inspect.setId(3L);
+ inspect.setInspectState(0);
+ inspect.setCheckResult("鍚堟牸");
+ when(inspectService.getById(3L)).thenReturn(inspect);
+
+ QualityInspectParam parameter = new QualityInspectParam();
+ parameter.setId(5L);
+ parameter.setInspectId(3L);
+ parameter.setParameterItem("鍘氬害");
+ parameter.setControlValue("1.95~2.05");
+ parameter.setTestValue("99");
+
+ AjaxResult result = controller.update(Collections.singletonList(parameter));
+
+ assertTrue(result.isError());
+ verify(paramService, never()).updateBatchById(anyList());
+ }
+}
--
Gitblit v1.9.3