Browse Source

2026-07-16

RoHS增加【更新失效日期】功能
master
fengyuan_yang 2 weeks ago
parent
commit
4ad72b9422
  1. 22
      src/main/java/com/spring/modules/rohs/controller/RohsController.java
  2. 5
      src/main/java/com/spring/modules/rohs/entity/RohsEntity.java
  3. 2
      src/main/java/com/spring/modules/rohs/mapper/RohsMapper.java
  4. 10
      src/main/java/com/spring/modules/rohs/service/RohsService.java
  5. 131
      src/main/java/com/spring/modules/rohs/service/impl/RohsServiceImpl.java
  6. 30
      src/main/java/com/spring/modules/rohs/task/RohsExpiryFlagTask.java
  7. 1
      src/main/resources/application-dev.yml
  8. 23
      src/main/resources/mapper/rohs/RohsMapper.xml

22
src/main/java/com/spring/modules/rohs/controller/RohsController.java

@ -154,6 +154,9 @@ public class RohsController {
if (StringUtils.isBlank(rohs.getRejectFlag())) {
rohs.setRejectFlag("N");
}
if (StringUtils.isBlank(rohs.getIsExpiring())) {
rohs.setIsExpiring("N");
}
sanitizeHsfStandard(rohs);
rohsService.save(rohs);
rohsService.saveOrUpdateMaterials(rohs);
@ -182,6 +185,9 @@ public class RohsController {
if (StringUtils.isBlank(rohs.getStatus())) {
rohs.setStatus(exists.getStatus());
}
if (StringUtils.isBlank(rohs.getIsExpiring())) {
rohs.setIsExpiring(exists.getIsExpiring());
}
rohs.setUpdateDate(new Date());
if (StringUtils.isBlank(rohs.getUpdateBy())) {
rohs.setUpdateBy(currentUserName);
@ -271,6 +277,22 @@ public class RohsController {
return R.ok();
}
/**
* 已完成且即将失效单据更新失效日期
*/
@PostMapping("/updateExpiryInfo")
public R updateExpiryInfo(@RequestBody RohsEntity rohs) {
if (StringUtils.isBlank(rohs.getSite()) || StringUtils.isBlank(rohs.getReferenceNo())) {
return R.error("工厂(site)和序列号(referenceNo)不能为空");
}
try {
RohsEntity latest = rohsService.updateCompletedExpiryInfo(rohs, getCurrentUserName());
return R.ok().put("data", latest);
} catch (RuntimeException e) {
return R.error(e.getMessage());
}
}
/**
* 下达
*/

5
src/main/java/com/spring/modules/rohs/entity/RohsEntity.java

@ -194,6 +194,11 @@ public class RohsEntity implements Serializable {
*/
private String rohsStatus;
/**
* 即将失效标识Y/N
*/
private String isExpiring;
/**
* 报告有效期
*/

2
src/main/java/com/spring/modules/rohs/mapper/RohsMapper.java

@ -31,4 +31,6 @@ public interface RohsMapper extends BaseMapper<RohsEntity> {
IPage<Map<String, Object>> queryProjectMaterialPage(IPage<?> page, @Param("params") Map<String, Object> params);
List<RohsMaterialEntity> queryMaterialList(@Param("site") String site, @Param("referenceNo") String referenceNo);
int refreshAboutToExpireFlag();
}

10
src/main/java/com/spring/modules/rohs/service/RohsService.java

@ -78,6 +78,16 @@ public interface RohsService extends IService<RohsEntity> {
*/
void removeMaterials(String site, String referenceNo);
/**
* 已完成且即将失效单据更新失效日期相关字段
*/
RohsEntity updateCompletedExpiryInfo(RohsEntity rohs, String userName);
/**
* 刷新即将失效标识
*/
int refreshAboutToExpireFlag();
/**
* 流程干预提交节点更新/流程干预
*/

131
src/main/java/com/spring/modules/rohs/service/impl/RohsServiceImpl.java

@ -39,6 +39,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
@ -488,6 +490,60 @@ public class RohsServiceImpl extends ServiceImpl<RohsMapper, RohsEntity> impleme
rohsMaterialService.remove(removeWrapper);
}
@Override
@Transactional
public RohsEntity updateCompletedExpiryInfo(RohsEntity rohs, String userName) {
if (rohs == null || StringUtils.isBlank(rohs.getSite()) || StringUtils.isBlank(rohs.getReferenceNo())) {
throw new RuntimeException("工厂(site)和序列号(referenceNo)不能为空");
}
RohsEntity exists = this.getDetail(rohs.getSite(), rohs.getReferenceNo());
if (exists == null) {
throw new RuntimeException("未找到对应RoHs单据");
}
if (!"已完成".equals(exists.getStatus())) {
throw new RuntimeException("仅已完成状态的单据允许更新失效日期");
}
if (!"Y".equalsIgnoreCase(StringUtils.trimToEmpty(exists.getIsExpiring()))) {
throw new RuntimeException("当前单据非即将失效状态,不允许更新失效日期");
}
if (rohs.getExpiredDate() == null) {
throw new RuntimeException("报告日期不能为空");
}
Integer validUntilValue = rohs.getValidUntilValue();
if (validUntilValue == null || validUntilValue <= 0) {
throw new RuntimeException("有效期数值必须大于0");
}
String validUntil = StringUtils.trimToEmpty(rohs.getValidUntil());
if (StringUtils.isBlank(validUntil)) {
throw new RuntimeException("有效期单位不能为空");
}
Date expiryDate = calculateExpiryDateFromRule(rohs.getExpiredDate(), validUntilValue, validUntil);
if (expiryDate == null) {
throw new RuntimeException("有效期单位不合法,无法计算失效日期");
}
RohsEntity updateEntity = new RohsEntity();
updateEntity.setExpiredDate(rohs.getExpiredDate());
updateEntity.setValidUntilValue(validUntilValue);
updateEntity.setValidUntil(validUntil);
updateEntity.setExpiryDate(expiryDate);
updateEntity.setIsExpiring(isAboutToExpire(expiryDate) ? "Y" : "N");
updateEntity.setUpdateDate(new Date());
updateEntity.setUpdateBy(StringUtils.isNotBlank(userName) ? userName : exists.getUpdateBy());
QueryWrapper<RohsEntity> updateWrapper = new QueryWrapper<>();
updateWrapper.eq("site", rohs.getSite()).eq("reference_no", rohs.getReferenceNo());
this.update(updateEntity, updateWrapper);
return this.getDetail(rohs.getSite(), rohs.getReferenceNo());
}
@Override
@Transactional
public int refreshAboutToExpireFlag() {
return this.baseMapper.refreshAboutToExpireFlag();
}
/**
* 流程干预提交节点更新/流程干预
*/
@ -746,4 +802,79 @@ public class RohsServiceImpl extends ServiceImpl<RohsMapper, RohsEntity> impleme
rohs.setHsfStandard("");
}
}
private Date calculateExpiryDateFromRule(Date expiredDate, Integer validUntilValue, String validUntilUnit) {
if (expiredDate == null || validUntilValue == null || validUntilValue <= 0) {
return null;
}
String unitType = normalizeValidUntilUnitType(validUntilUnit);
if (StringUtils.isBlank(unitType)) {
return null;
}
LocalDate baseDate = toLocalDate(expiredDate);
if (baseDate == null) {
return null;
}
LocalDate resultDate;
switch (unitType) {
case "day":
resultDate = baseDate.plusDays(validUntilValue.longValue());
break;
case "week":
resultDate = baseDate.plusWeeks(validUntilValue.longValue());
break;
case "month":
resultDate = baseDate.plusMonths(validUntilValue.longValue());
break;
case "year":
resultDate = baseDate.plusYears(validUntilValue.longValue());
break;
default:
return null;
}
return java.sql.Date.valueOf(resultDate);
}
private String normalizeValidUntilUnitType(String unitValue) {
String text = StringUtils.trimToEmpty(unitValue).toLowerCase();
if (StringUtils.isBlank(text)) {
return "";
}
if ("d".equals(text) || "day".equals(text) || "days".equals(text)
|| text.contains("日") || text.contains("天")) {
return "day";
}
if ("w".equals(text) || "week".equals(text) || "weeks".equals(text) || text.contains("周")) {
return "week";
}
if ("m".equals(text) || "month".equals(text) || "months".equals(text) || text.contains("月")) {
return "month";
}
if ("y".equals(text) || "year".equals(text) || "years".equals(text) || text.contains("年")) {
return "year";
}
return "";
}
private boolean isAboutToExpire(Date expiryDate) {
LocalDate expiryLocalDate = toLocalDate(expiryDate);
if (expiryLocalDate == null) {
return false;
}
LocalDate limitDate = LocalDate.now().plusMonths(1);
return !expiryLocalDate.isAfter(limitDate);
}
private LocalDate toLocalDate(Date date) {
if (date == null) {
return null;
}
// java.sql.Date may throw UnsupportedOperationException on toInstant()
if (date instanceof java.sql.Date) {
return ((java.sql.Date) date).toLocalDate();
}
return java.time.Instant.ofEpochMilli(date.getTime())
.atZone(ZoneId.systemDefault())
.toLocalDate();
}
}

30
src/main/java/com/spring/modules/rohs/task/RohsExpiryFlagTask.java

@ -0,0 +1,30 @@
package com.spring.modules.rohs.task;
import com.spring.modules.rohs.service.RohsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 刷新RoHS即将失效标识定时任务
*/
@Component
public class RohsExpiryFlagTask {
private static final Logger logger = LoggerFactory.getLogger(RohsExpiryFlagTask.class);
@Autowired
private RohsService rohsService;
@Scheduled(cron = "${task.data.refreshRohsAboutToExpireFlag}")
public void refreshAboutToExpireFlag() {
try {
int affectedRows = rohsService.refreshAboutToExpireFlag();
logger.info("RoHS即将失效标识刷新完成,更新记录数={}", affectedRows);
} catch (Exception e) {
logger.error("RoHS即将失效标识刷新失败,error={}", e.getMessage(), e);
}
}
}

1
src/main/resources/application-dev.yml

@ -104,6 +104,7 @@ task:
sync_part_catalog_to_plm: 0 0 0 29 2 ? # 每1分钟执行
syncInventoryPartToPlm: 0 */10 * * * ? # 每10分钟执行
refreshLdapAccountToRedis: 0 0 0 * * ? #
refreshRohsAboutToExpireFlag: 0 0 1 * * ? # 每天凌晨1点刷新RoHS即将失效标识
flag: false
pool:
schedulerSize: 10

23
src/main/resources/mapper/rohs/RohsMapper.xml

@ -38,6 +38,7 @@
<result column="status" property="status" />
<result column="sgs_report_number" property="sgsReportNumber" />
<result column="rohs_status" property="rohsStatus" />
<result column="is_expiring" property="isExpiring" />
<result column="expired_date" property="expiredDate" />
<result column="expiry_date" property="expiryDate" />
<result column="fiber_information" property="fiberInformation" />
@ -94,7 +95,7 @@
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
a.site, a.reference_no, a.applicant, a.application_date, a.process, a.bu_no, a.pm, a.planned_mass_production_date, a.color, a.vendor_code, a.vendor_material_code, a.material_classify, a.other_material_classify, a.material_use_for, a.end_customer, a.project_id, a.is_macallan_material, a.need_create_number, a.npd_engineer, a.material_validity_time, a.material_validity_comments, a.need_deviation, a.technical_plan, a.wm_required_spec, a.is_fiber_material, a.material_thickness, a.buyer, a.expect_report_time, a.qualification_documents_needed, a.test_report_including_items, a.remark, a.status, a.sgs_report_number, a.rohs_status, a.expired_date, a.expiry_date, a.fiber_information, a.hsf_standard, a.hsf_approver, a.related_people, a.valid_until_value, a.valid_until, a.is_meet_rohs_requirement, a.is_ah_grade, a.hsf_supplier_classification, a.material_desc, a.npd_remark, a.is_same_material_diff_size, a.ifs_part_no, a.comm_group1, a.comm_group2, a.comm_group3, a.create_date, a.create_by, a.update_date, a.update_by, a.step_id, a.reject_flag, a.reject_step_id
a.site, a.reference_no, a.applicant, a.application_date, a.process, a.bu_no, a.pm, a.planned_mass_production_date, a.color, a.vendor_code, a.vendor_material_code, a.material_classify, a.other_material_classify, a.material_use_for, a.end_customer, a.project_id, a.is_macallan_material, a.need_create_number, a.npd_engineer, a.material_validity_time, a.material_validity_comments, a.need_deviation, a.technical_plan, a.wm_required_spec, a.is_fiber_material, a.material_thickness, a.buyer, a.expect_report_time, a.qualification_documents_needed, a.test_report_including_items, a.remark, a.status, a.sgs_report_number, a.rohs_status, a.is_expiring, a.expired_date, a.expiry_date, a.fiber_information, a.hsf_standard, a.hsf_approver, a.related_people, a.valid_until_value, a.valid_until, a.is_meet_rohs_requirement, a.is_ah_grade, a.hsf_supplier_classification, a.material_desc, a.npd_remark, a.is_same_material_diff_size, a.ifs_part_no, a.comm_group1, a.comm_group2, a.comm_group3, a.create_date, a.create_by, a.update_date, a.update_by, a.step_id, a.reject_flag, a.reject_step_id
</sql>
<select id="getApprovalList" resultType="com.spring.modules.change.vo.ProcessFormVo">
@ -393,6 +394,26 @@
and a.reference_no = #{referenceNo}
</select>
<update id="refreshAboutToExpireFlag">
update plm_rohs
set is_expiring =
case
when status = '已完成'
and expiry_date is not null
and cast(expiry_date as date) <![CDATA[ <= ]]> dateadd(month, 1, cast(getdate() as date))
then 'Y'
else 'N'
end
where isnull(is_expiring, 'N') <![CDATA[ <> ]]>
case
when status = '已完成'
and expiry_date is not null
and cast(expiry_date as date) <![CDATA[ <= ]]> dateadd(month, 1, cast(getdate() as date))
then 'Y'
else 'N'
end
</update>
<select id="queryProjectMaterialPage" resultType="java.util.HashMap">
select
p.site as site,

Loading…
Cancel
Save