From 54ca760714d25c9401cde39abfb214694b93f28e Mon Sep 17 00:00:00 2001 From: fengyuan_yang <1976974459@qq.com> Date: Thu, 30 Apr 2026 13:52:29 +0800 Subject: [PATCH] =?UTF-8?q?2026-04-30=20RoHs=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rohs/controller/RohsController.java | 164 ++++++++++++++ .../modules/rohs/entity/RohsEntity.java | 209 ++++++++++++++++++ .../modules/rohs/mapper/RohsMapper.java | 12 + .../modules/rohs/service/RohsService.java | 28 +++ .../rohs/service/impl/RohsServiceImpl.java | 53 +++++ .../modules/rohs/task/RohsCleanTask.java | 56 +++++ src/main/resources/mapper/oss/SysOssDao.xml | 8 +- src/main/resources/mapper/rohs/RohsMapper.xml | 51 +++++ 8 files changed, 577 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/spring/modules/rohs/controller/RohsController.java create mode 100644 src/main/java/com/spring/modules/rohs/entity/RohsEntity.java create mode 100644 src/main/java/com/spring/modules/rohs/mapper/RohsMapper.java create mode 100644 src/main/java/com/spring/modules/rohs/service/RohsService.java create mode 100644 src/main/java/com/spring/modules/rohs/service/impl/RohsServiceImpl.java create mode 100644 src/main/java/com/spring/modules/rohs/task/RohsCleanTask.java create mode 100644 src/main/resources/mapper/rohs/RohsMapper.xml diff --git a/src/main/java/com/spring/modules/rohs/controller/RohsController.java b/src/main/java/com/spring/modules/rohs/controller/RohsController.java new file mode 100644 index 00000000..44f4f772 --- /dev/null +++ b/src/main/java/com/spring/modules/rohs/controller/RohsController.java @@ -0,0 +1,164 @@ +package com.spring.modules.rohs.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.spring.common.utils.PageUtils; +import com.spring.common.utils.R; +import com.spring.modules.oss.entity.SysOssEntity; +import com.spring.modules.oss.service.SysOssService; +import com.spring.modules.rohs.entity.RohsEntity; +import com.spring.modules.rohs.service.RohsService; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * RoHs Controller + */ +@RestController +@RequestMapping("/rohs") +public class RohsController { + + @Autowired + private RohsService rohsService; + + @Autowired + private SysOssService sysOssService; + + /** + * 列表查询 + */ + @GetMapping("/list") + public R list(@RequestParam Map params){ + PageUtils page = rohsService.queryPage(params); + return R.ok().put("page", page); + } + + /** + * 详情查询 + */ + @GetMapping("/info") + public R info(@RequestParam("site") String site, @RequestParam("referenceNo") String referenceNo){ + if (StringUtils.isBlank(site) || StringUtils.isBlank(referenceNo)) { + return R.error("工厂(site)和序列号(referenceNo)不能为空"); + } + RohsEntity rohs = rohsService.getDetail(site, referenceNo); + return R.ok().put("data", rohs); + } + + /** + * 保存 + */ + @PostMapping("/save") + @Transactional + public R save(@RequestBody RohsEntity rohs){ + if (StringUtils.isBlank(rohs.getSite()) || StringUtils.isBlank(rohs.getReferenceNo())) { + return R.error("工厂(site)和序列号(referenceNo)不能为空"); + } + + String originalReferenceNo = rohs.getReferenceNo(); + String newReferenceNo = originalReferenceNo; + + // 方案A:如果是前端传来的临时单号,则生成真实单号 (比如:RH20260428001) + if (originalReferenceNo.startsWith("TEMP-")) { + String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date()); + String prefix = "RH" + dateStr; + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.likeRight("reference_no", prefix); + queryWrapper.orderByDesc("reference_no"); + + // 为了兼容不同的数据库类型,此处通过列表方式获取第一条即为当天的最大号 + List list = rohsService.list(queryWrapper); + if (list != null && !list.isEmpty()) { + RohsEntity lastRecord = list.get(0); + String lastNo = lastRecord.getReferenceNo(); + // 判断后缀是否能提取为数字流水号 + if (lastNo != null && lastNo.length() >= 13) { + try { + int seq = Integer.parseInt(lastNo.substring(10)); + newReferenceNo = prefix + String.format("%03d", seq + 1); + } catch (NumberFormatException e) { + newReferenceNo = prefix + "001"; + } + } else { + newReferenceNo = prefix + "001"; + } + } else { + newReferenceNo = prefix + "001"; + } + + // 更新到实体类上准备入库 + rohs.setReferenceNo(newReferenceNo); + + // 【关键步骤】:将所有前端上传时的临时关联ID全部更新为正式生成的单据号 + // 约定:sys_oss.order_ref1 = site, sys_oss.order_ref2 = referenceNo + SysOssEntity updateOss = new SysOssEntity(); + updateOss.setOrderRef1(rohs.getSite()); + updateOss.setOrderRef2(newReferenceNo); + + QueryWrapper ossWrapper = new QueryWrapper<>(); + ossWrapper.eq("order_ref1", rohs.getSite()); + ossWrapper.eq("order_ref2", originalReferenceNo); + sysOssService.update(updateOss, ossWrapper); + + } else { + // 如果非 TEMP- 开头,仍需要校验主键是否重复 + RohsEntity exist = rohsService.getDetail(rohs.getSite(), rohs.getReferenceNo()); + if (exist != null) { + return R.error("该序列号(referenceNo)的申请记录已存在"); + } + } + + if (rohs.getApplicationDate() == null) { + rohs.setApplicationDate(new Date()); + } + + rohsService.save(rohs); + return R.ok().put("referenceNo", newReferenceNo); + } + + /** + * 修改 + */ + @PostMapping("/update") + public R update(@RequestBody RohsEntity rohs){ + if (StringUtils.isBlank(rohs.getSite()) || StringUtils.isBlank(rohs.getReferenceNo())) { + return R.error("工厂(site)和序列号(referenceNo)不能为空"); + } + + QueryWrapper updateWrapper = new QueryWrapper<>(); + updateWrapper.eq("site", rohs.getSite()).eq("reference_no", rohs.getReferenceNo()); + + rohsService.update(rohs, updateWrapper); + return R.ok(); + } + + /** + * 删除 (扩展) + */ + @PostMapping("/delete") + @Transactional + public R delete(@RequestBody RohsEntity rohs){ + if (StringUtils.isBlank(rohs.getSite()) || StringUtils.isBlank(rohs.getReferenceNo())) { + return R.error("工厂(site)和序列号(referenceNo)不能为空"); + } + + QueryWrapper deleteWrapper = new QueryWrapper<>(); + deleteWrapper.eq("site", rohs.getSite()).eq("reference_no", rohs.getReferenceNo()); + rohsService.remove(deleteWrapper); + + // 连同关联的附件数据一并清理 + QueryWrapper ossWrapper = new QueryWrapper<>(); + ossWrapper.eq("order_ref1", rohs.getReferenceNo()); + ossWrapper.eq("order_ref2", rohs.getSite()); + sysOssService.remove(ossWrapper); + + return R.ok(); + } +} diff --git a/src/main/java/com/spring/modules/rohs/entity/RohsEntity.java b/src/main/java/com/spring/modules/rohs/entity/RohsEntity.java new file mode 100644 index 00000000..10d33976 --- /dev/null +++ b/src/main/java/com/spring/modules/rohs/entity/RohsEntity.java @@ -0,0 +1,209 @@ +package com.spring.modules.rohs.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * RoHs材料管理实体类 + */ +@Data +@TableName("plm_rohs") +public class RohsEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 工厂 + */ + private String site; + + /** + * 序列号 + */ + private String referenceNo; + + /** + * 申请人 + */ + private String applicant; + + /** + * 申请日期 + */ + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date applicationDate; + + /** + * 工艺 + */ + private String process; + + /** + * 供应商 + */ + private String vendorCode; + + /** + * 供应商材料编号 + */ + private String vendorMaterialCode; + + /** + * 材料分类 + */ + private String materialClassify; + + /** + * 其他材料分类 + */ + private String otherMaterialClassify; + + /** + * 辅材用途 + */ + private String materialUseFor; + + /** + * 最终客户 + */ + private String endCustomer; + + /** + * 项目编码 + */ + private String projectId; + + /** + * 是否是Macallan材料 + */ + private String isMacallanMaterial; + + /** + * 是否需要创建300/700/900编号 + */ + private String needCreateNumber; + + /** + * NPD工程师 + */ + private String npdEngineer; + + /** + * 材料有效期 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date materialValidityTime; + + /** + * 材料有效期备注 + */ + private String materialValidityComments; + + /** + * 是否需要偏差许可 + */ + private String needDeviation; + + /** + * 技术计划 + */ + private String technicalPlan; + + /** + * WM所需求规格 + */ + private String wmRequiredSpec; + + /** + * 是否是Fiber材料 + */ + private String isFiberMaterial; + + /** + * 材料厚度 + */ + private String materialThickness; + + /** + * 采购 + */ + private String buyer; + + /** + * 预计提供报告时间(个月内) + */ + private Integer expectReportTime; + + /** + * 所需审批文件 + */ + private String qualificationDocumentsNeeded; + + /** + * 测试报告必测项目 + */ + private String testReportIncludingItems; + + /** + * 备注说明 + */ + private String remark; + + /** + * 状态 + */ + private String status; + + /** + * SGS报告编号 + */ + private String sgsReportNumber; + + /** + * 报告有效期 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date expiredDate; + + /** + * Fiber报告信息 + */ + private String fiberInformation; + + /** + * HSF标准 + */ + private String hsfStandard; + + /** + * 材料是否符合RoHS要求 + */ + private String isMeetRohsRequirement; + + /** + * 符合HSF供应商等级 + */ + private String hsfSupplierClassification; + + /** + * 材料描述 + */ + private String materialDesc; + + /** + * 现有材料不同规格 + */ + private String isSameMaterialDiffSize; + + /** + * 材料IFS编号 + */ + private String ifsPartNo; +} diff --git a/src/main/java/com/spring/modules/rohs/mapper/RohsMapper.java b/src/main/java/com/spring/modules/rohs/mapper/RohsMapper.java new file mode 100644 index 00000000..b8a8e91b --- /dev/null +++ b/src/main/java/com/spring/modules/rohs/mapper/RohsMapper.java @@ -0,0 +1,12 @@ +package com.spring.modules.rohs.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.spring.modules.rohs.entity.RohsEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * RoHsMapper + */ +@Mapper +public interface RohsMapper extends BaseMapper { +} diff --git a/src/main/java/com/spring/modules/rohs/service/RohsService.java b/src/main/java/com/spring/modules/rohs/service/RohsService.java new file mode 100644 index 00000000..c49bf039 --- /dev/null +++ b/src/main/java/com/spring/modules/rohs/service/RohsService.java @@ -0,0 +1,28 @@ +package com.spring.modules.rohs.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.spring.common.utils.PageUtils; +import com.spring.modules.rohs.entity.RohsEntity; + +import java.util.Map; + +/** + * RoHs Service + */ +public interface RohsService extends IService { + + /** + * 分页查询 + * @param params 查询参数 + * @return 分页数据 + */ + PageUtils queryPage(Map params); + + /** + * 详情查询 + * @param site 工厂 + * @param referenceNo 序列号 + * @return 详情 + */ + RohsEntity getDetail(String site, String referenceNo); +} diff --git a/src/main/java/com/spring/modules/rohs/service/impl/RohsServiceImpl.java b/src/main/java/com/spring/modules/rohs/service/impl/RohsServiceImpl.java new file mode 100644 index 00000000..c268f612 --- /dev/null +++ b/src/main/java/com/spring/modules/rohs/service/impl/RohsServiceImpl.java @@ -0,0 +1,53 @@ +package com.spring.modules.rohs.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.spring.common.utils.PageUtils; +import com.spring.common.utils.Query; +import com.spring.modules.rohs.entity.RohsEntity; +import com.spring.modules.rohs.mapper.RohsMapper; +import com.spring.modules.rohs.service.RohsService; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service("rohsService") +public class RohsServiceImpl extends ServiceImpl implements RohsService { + + @Override + public PageUtils queryPage(Map params) { + String site = (String) params.get("site"); + String referenceNo = (String) params.get("referenceNo"); + String applicant = (String) params.get("applicant"); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (StringUtils.isNotBlank(site)) { + queryWrapper.eq("site", site); + } + if (StringUtils.isNotBlank(referenceNo)) { + queryWrapper.like("reference_no", referenceNo); + } + if (StringUtils.isNotBlank(applicant)) { + queryWrapper.like("applicant", applicant); + } + + // 默认按申请时间倒序排序 + queryWrapper.orderByDesc("application_date"); + + IPage page = this.page( + new Query().getPage(params), + queryWrapper + ); + + return new PageUtils(page); + } + + @Override + public RohsEntity getDetail(String site, String referenceNo) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("site", site).eq("reference_no", referenceNo); + return this.getOne(queryWrapper); + } +} diff --git a/src/main/java/com/spring/modules/rohs/task/RohsCleanTask.java b/src/main/java/com/spring/modules/rohs/task/RohsCleanTask.java new file mode 100644 index 00000000..bc7ec1bf --- /dev/null +++ b/src/main/java/com/spring/modules/rohs/task/RohsCleanTask.java @@ -0,0 +1,56 @@ +package com.spring.modules.rohs.task; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.spring.modules.oss.entity.SysOssEntity; +import com.spring.modules.oss.service.SysOssService; +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; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * 清理RoHs临时垃圾文件的定时任务 + */ +@Component +public class RohsCleanTask { + + private static final Logger logger = LoggerFactory.getLogger(RohsCleanTask.class); + + @Autowired + private SysOssService sysOssService; + + /** + * 每天凌晨0点执行,清理创建时间超过24小时的无效临时附件记录 + */ + @Scheduled(cron = "0 0 0 * * ?") + public void cleanTempFiles() { + logger.info("============== 开始清理RoHs临时垃圾附件 =============="); + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_MONTH, -1); + Date yesterday = calendar.getTime(); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + // 查找 order_ref1 包含 TEMP- 并且创建时间在昨天之前(超过24小时)的记录 + queryWrapper.likeRight("order_ref1", "TEMP-"); + queryWrapper.lt("create_date", yesterday); + + List garbageList = sysOssService.list(queryWrapper); + if (garbageList != null && !garbageList.isEmpty()) { + logger.info("找到 {} 条过期临时附件,准备清理...", garbageList.size()); + + // 物理删除和OSS清理依赖于您系统的文件处理策略 + // 这里我们主要将垃圾脏数据的数据库记录删除 + sysOssService.remove(queryWrapper); + + logger.info("============== RoHs临时垃圾附件清理完成 =============="); + } else { + logger.info("============== 没有发现过期的临时垃圾附件 =============="); + } + } +} diff --git a/src/main/resources/mapper/oss/SysOssDao.xml b/src/main/resources/mapper/oss/SysOssDao.xml index 847fe8d9..8deead7d 100644 --- a/src/main/resources/mapper/oss/SysOssDao.xml +++ b/src/main/resources/mapper/oss/SysOssDao.xml @@ -6,7 +6,7 @@