From 9335bc90417c44960deacaed78d79daed3763c7c Mon Sep 17 00:00:00 2001 From: mashuai Date: Sat, 21 Jun 2025 11:00:18 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/biz/domain/lease/LeaseOutSign.java | 22 ++++++ .../service/impl/ArchivesServiceImpl.java | 5 ++ .../controller/BackApplyInfoController.java | 21 +++++ .../back/service/IBackApplyInfoService.java | 14 ++++ .../impl/BackApplyInfoServiceImpl.java | 56 ++++++++++++- .../lease/domain/vo/LeaseApplyRequestVo.java | 7 +- .../lease/mapper/LeaseApplyInfoMapper.java | 8 ++ .../impl/LeaseApplyInfoServiceImpl.java | 30 +++++-- .../impl/LeaseOutDetailsServiceImpl.java | 2 +- .../domain/vo/PurchaseCheckFormVo.java | 5 +- .../scrap/domain/vo/ScrapDetailsListVo.java | 2 +- .../material/back/BackApplyInfoMapper.xml | 79 +++++++++++-------- .../material/lease/LeaseApplyInfoMapper.xml | 15 +++- 13 files changed, 216 insertions(+), 50 deletions(-) create mode 100644 bonus-common-biz/src/main/java/com/bonus/common/biz/domain/lease/LeaseOutSign.java diff --git a/bonus-common-biz/src/main/java/com/bonus/common/biz/domain/lease/LeaseOutSign.java b/bonus-common-biz/src/main/java/com/bonus/common/biz/domain/lease/LeaseOutSign.java new file mode 100644 index 00000000..f132efc7 --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/biz/domain/lease/LeaseOutSign.java @@ -0,0 +1,22 @@ +package com.bonus.common.biz.domain.lease; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * @Author ma_sh + * @create 2025/6/20 17:16 + */ +@EqualsAndHashCode(callSuper = false) +@Data +@ToString +public class LeaseOutSign { + + @ApiModelProperty(value = "出库人签名URL") + private String outSignUrl; + + @ApiModelProperty(value = "出库人签名类型") + private int outSignType; +} diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/archives/service/impl/ArchivesServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/archives/service/impl/ArchivesServiceImpl.java index 41193f0c..f10d3ef4 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/archives/service/impl/ArchivesServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/archives/service/impl/ArchivesServiceImpl.java @@ -608,6 +608,11 @@ public class ArchivesServiceImpl implements ArchivesService { } info.setUserId(userId); ElcSignatureInfo elcSignatureInfo = archivesMapper.getSign(info); + if (elcSignatureInfo != null) { + if (StringUtils.isNotBlank(elcSignatureInfo.getSignUrl())) { + elcSignatureInfo.setSignUrl("data:image/png;base64," + elcSignatureInfo.getSignUrl()); + } + } return AjaxResult.success(elcSignatureInfo); } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/controller/BackApplyInfoController.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/controller/BackApplyInfoController.java index 00aa94f5..02c8d56f 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/controller/BackApplyInfoController.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/controller/BackApplyInfoController.java @@ -156,6 +156,17 @@ public class BackApplyInfoController extends BaseController { return backApplyInfoService.getMachineById(dto); } + /** + * 根据单位和工程id查询领料机具 + * @param dto + * @return + */ + @ApiOperation(value = "根据单位和工程id查询领料机具") + @GetMapping("/selectMachineById") + public AjaxResult selectMachineById(BackApplyInfo dto){ + return backApplyInfoService.selectMachineById(dto); + } + /** * app根据设备编码去检索领料详情 * @param dto @@ -326,6 +337,16 @@ public class BackApplyInfoController extends BaseController { return backApplyInfoService.deleteBackApplyInfoById(backApplyInfo.getId()); } + /** + * todo :删除退料任务,仅供app使用(整张单据删除时,里面有内容,不允许删除) + */ + @ApiOperation(value = "APP删除退料任务") + @PreventRepeatSubmit + @PostMapping("/deleteByApp") + public AjaxResult deleteByApp(@RequestBody BackApplyInfo backApplyInfo) { + return backApplyInfoService.deleteByApp(backApplyInfo.getId()); + } + /** * app内层删除退料任务 */ diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/service/IBackApplyInfoService.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/service/IBackApplyInfoService.java index fd373809..13313097 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/service/IBackApplyInfoService.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/service/IBackApplyInfoService.java @@ -151,5 +151,19 @@ public interface IBackApplyInfoService { * @return */ BackApplyInfoVo selectSecondList(BackApplyInfoVo dto); + + /** + * 根据单位和工程id查询领料机具 + * @param dto + * @return + */ + AjaxResult selectMachineById(BackApplyInfo dto); + + /** + * APP删除退料任务 + * @param id + * @return + */ + AjaxResult deleteByApp(Long id); } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/service/impl/BackApplyInfoServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/service/impl/BackApplyInfoServiceImpl.java index 28a6c357..283dad89 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/service/impl/BackApplyInfoServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/back/service/impl/BackApplyInfoServiceImpl.java @@ -92,7 +92,9 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService { String directAuditUrl = backApplyInfoMapper.getDirectAuditUrl(backApplyInfo); backApplyInfo.setDirectAuditSignUrl(directAuditUrl); /** 设置审批人签名url 防止代码冲突 **/ - + if (StringUtils.isNotBlank(backApplyInfo.getBackSignUrl())) { + backApplyInfo.setBackSignUrl("data:image/png;base64," + backApplyInfo.getBackSignUrl()); + } backApplyRequestVo.setBackApplyInfo(backApplyInfo); //查询退料详情信息 backApplyInfo.setKeyWord(keyWord); @@ -1176,7 +1178,7 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService { @Override public AjaxResult getMachine(BackApplyInfo dto) { // 首先根据id、maCode或者qrCode进行查询,看此条数据是否已经存在该退料单中 - if (dto.getId() != null) { + if (dto.getId() != null && (StringUtils.isNotBlank(dto.getMaCode()) || StringUtils.isNotBlank(dto.getQrCode()))) { List maCodeVoList = backApplyInfoMapper.getMachineByIdAndCode(dto); if (CollectionUtils.isNotEmpty(maCodeVoList)) { return AjaxResult.error("该编码已存在该退料单中,请重新选择"); @@ -1197,7 +1199,7 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService { } return AjaxResult.success(list); } - return AjaxResult.error(HttpCodeEnum.SYSTEM_ERROR.getCode(), "编码检索为空"); + return AjaxResult.error(HttpCodeEnum.SYSTEM_ERROR.getCode(), "检索为空或该设备非该单位和工程所领"); } /** @@ -1439,6 +1441,54 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService { return vo; } + /** + * 根据单位和工程id查询领料机具 + * @param dto + * @return + */ + @Override + public AjaxResult selectMachineById(BackApplyInfo dto) { + List list = backApplyInfoMapper.getMachineById(dto); + if (CollectionUtils.isNotEmpty(list)) { + // 根据id查询该单据可能存在的设备编码 + List maCodeVos = backApplyInfoMapper.selectByCode(dto.getId()); + if (CollectionUtils.isNotEmpty(maCodeVos)) { + // 获取maCodeVos中的编码 + List maCodes = maCodeVos.stream().map(MaCodeVo::getMaCode).collect(Collectors.toList()); + // 将maCodes中存在于list集合中的编码,把数据从list集合中去除 + list = list.stream(). + filter(info -> !maCodes.contains(info.getMaCode())). + collect(Collectors.toList()); + } + } + return AjaxResult.success(list); + } + + /** + * APP删除退料任务 + * @param id + * @return + */ + @Override + public AjaxResult deleteByApp(Long id) { + try { + // 查询信息 + BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id); + List backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(backApplyInfo); + if (CollectionUtils.isNotEmpty(backApplyDetailsList)) { + return AjaxResult.error("该单据中存在相关退料数据,不允许删除"); + } + // 删除相关任务信息 + int result = deleteTaskInfo(backApplyInfo); + if (result > 0) { + return AjaxResult.success(result); + } + } catch (Exception e) { + e.printStackTrace(); + } + return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg()); + } + /** * 关键字搜索 diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/domain/vo/LeaseApplyRequestVo.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/domain/vo/LeaseApplyRequestVo.java index 5114e773..319899f6 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/domain/vo/LeaseApplyRequestVo.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/domain/vo/LeaseApplyRequestVo.java @@ -1,7 +1,7 @@ package com.bonus.material.lease.domain.vo; +import com.bonus.common.biz.domain.lease.LeaseOutSign; import com.bonus.common.core.web.domain.BaseEntity; -import com.bonus.material.back.domain.vo.MaCodeVo; import com.bonus.material.lease.domain.LeaseApplyDetails; import com.bonus.common.biz.domain.lease.LeaseApplyInfo; import io.swagger.annotations.ApiModelProperty; @@ -34,6 +34,11 @@ public class LeaseApplyRequestVo extends BaseEntity { private List leaseOutVoList; + /** + * 库管签名集合 + */ + private List kgSignList; + private int statusFlag; } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/mapper/LeaseApplyInfoMapper.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/mapper/LeaseApplyInfoMapper.java index e7aa1011..79662cdf 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/mapper/LeaseApplyInfoMapper.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/mapper/LeaseApplyInfoMapper.java @@ -3,6 +3,7 @@ package com.bonus.material.lease.mapper; import java.util.Date; import java.util.List; import com.bonus.common.biz.domain.lease.LeaseApplyInfo; +import com.bonus.common.biz.domain.lease.LeaseOutSign; import org.apache.ibatis.annotations.Param; /** @@ -99,4 +100,11 @@ public interface LeaseApplyInfoMapper { * @return */ List getNoSignList(LeaseApplyInfo leaseApplyInfo); + + /** + * 查询领料单的领料单出库签名 + * @param id + * @return + */ + List selectLeaseApplyOutList(Long id); } diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/service/impl/LeaseApplyInfoServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/service/impl/LeaseApplyInfoServiceImpl.java index 49f815db..2484dd5a 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/service/impl/LeaseApplyInfoServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/service/impl/LeaseApplyInfoServiceImpl.java @@ -10,6 +10,7 @@ import cn.hutool.core.collection.CollectionUtil; import com.bonus.common.biz.config.PoiOutPage; import com.bonus.common.biz.constant.MaterialConstants; import com.bonus.common.biz.domain.BmFileInfo; +import com.bonus.common.biz.domain.lease.LeaseOutSign; import com.bonus.common.biz.enums.HttpCodeEnum; import com.bonus.common.biz.enums.LeaseTaskStatusEnum; import com.bonus.common.biz.enums.MaMachineStatusEnum; @@ -122,6 +123,10 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService { String sendUnit = leaseApplyInfoMapper.getSendUnit(info); info.setSendUnit(sendUnit); } + // 电子签名进行base64拼接 + if (StringUtils.isNotBlank(info.getLeaseSignUrl())) { + info.setLeaseSignUrl("data:image/png;base64," + info.getLeaseSignUrl()); + } /** 设置发料单位 防止代码冲突 **/ leaseApplyRequestVo.setLeaseApplyInfo(info); @@ -156,6 +161,16 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService { } } } + // 根据id查询领料出库情况,查询出库人电子签名详情 + List outSignList = leaseApplyInfoMapper.selectLeaseApplyOutList(id); + if (!CollectionUtils.isEmpty(outSignList)) { + for (LeaseOutSign applyInfo : outSignList) { + if (StringUtils.isNotBlank(applyInfo.getOutSignUrl())) { + applyInfo.setOutSignUrl("data:image/png;base64," + applyInfo.getOutSignUrl()); + } + } + leaseApplyRequestVo.setKgSignList(outSignList); + } }); @@ -179,7 +194,7 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService { List list = leaseApplyInfoMapper.selectLeaseApplyInfoList(leaseApplyInfo); // 如果statusList包含3、4、5,则为领料出库查询,需查询领用出库数据,进行拼接 if (!CollectionUtils.isEmpty(leaseApplyInfo.getStatusList())) { - if (leaseApplyInfo.getStatusList().contains(3) || leaseApplyInfo.getStatusList().contains(4) || leaseApplyInfo.getStatusList().contains(5)) { + if (leaseApplyInfo.getStatusList().containsAll(Arrays.asList(3, 4, 5))) { // 查询领用出库数据 List leaseApplyOutList = leaseApplyInfoMapper.selectPublishList(leaseApplyInfo); if (!CollectionUtils.isEmpty(leaseApplyOutList)) { @@ -209,7 +224,8 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService { } // 使用 Stream API 进行降序排序 List sortedList = list.stream() - .sorted(Comparator.comparing(LeaseApplyInfo::getCreateTime).reversed()) + .sorted(Comparator.comparing(LeaseApplyInfo::getCreateTime, + Comparator.nullsFirst(Comparator.naturalOrder())).reversed()) .collect(Collectors.toList()); if (!CollectionUtils.isEmpty(sortedList)) { String keyWord = leaseApplyInfo.getKeyWord(); @@ -274,9 +290,9 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService { } // 使用 Stream API 进行降序排序 List sortedList = list.stream() - .sorted(Comparator.comparing(LeaseApplyInfo::getCreateTime).reversed()) + .sorted(Comparator.comparing(LeaseApplyInfo::getCreateTime, + Comparator.nullsFirst(Comparator.naturalOrder())).reversed()) .collect(Collectors.toList()); - if (!CollectionUtils.isEmpty(sortedList)) { String keyWord = leaseApplyInfo.getKeyWord(); // 如果关键字不为空,进行过滤 @@ -779,12 +795,12 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService { if (CollectionUtil.isNotEmpty(recordList)) { recordList = recordList.stream().filter(item -> item.getMaStatus().equals(MaMachineStatusEnum.IN_STORE.getStatus().toString())).collect(Collectors.toList()); if (recordList.size() > 0) { - msg = "监测到" + bmQrcodeInfo.getQrCode() + "符合出库条件,请确认是否出库!"; + msg = "监测到当前设备符合出库条件,请确认是否出库!"; }else{ - msg = "监测到" + bmQrcodeInfo.getQrCode() + "编码不符合出库条件,请检查后重新提交!"; + msg = "监测到当前设备不符合出库条件,无法出库!"; } } else { - msg = "监测到" + bmQrcodeInfo.getQrCode() + "编码不符合出库条件,请检查后重新提交!"; + msg = "监测到当前设备不符合出库条件,无法出库!!"; } // 返回包含设备列表和消息的结果 Map result = new HashMap<>(2); diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/service/impl/LeaseOutDetailsServiceImpl.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/service/impl/LeaseOutDetailsServiceImpl.java index ef0b2142..c5ca9099 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/service/impl/LeaseOutDetailsServiceImpl.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/lease/service/impl/LeaseOutDetailsServiceImpl.java @@ -443,7 +443,7 @@ public class LeaseOutDetailsServiceImpl implements ILeaseOutDetailsService { } if (res > 0) { // 插入领料出库明细表(lease_out_details) - record.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName()); + record.setCreateBy(SecurityUtils.getLoginUser().getUserid().toString()); res = leaseOutDetailsMapper.insertLeaseOutDetails(record); if (res > 0) { // 普通机具减少 (ma_type 设备规格表)的库存数量 diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/vo/PurchaseCheckFormVo.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/vo/PurchaseCheckFormVo.java index 43fc3270..7d49c880 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/vo/PurchaseCheckFormVo.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/purchase/domain/vo/PurchaseCheckFormVo.java @@ -3,10 +3,12 @@ package com.bonus.material.purchase.domain.vo; import com.bonus.material.archives.domain.ElcSignatureInfo; import com.bonus.material.purchase.domain.PurchaseCheckDetails; import com.bonus.material.purchase.domain.PurchaseSignRecord; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.ArrayList; +import java.util.Date; import java.util.List; /** @@ -27,7 +29,8 @@ public class PurchaseCheckFormVo { private String supplier; @ApiModelProperty(value = "到货日期") - private String arrivalDate; + @JsonFormat(pattern = "yyyy-MM-dd") + private Date arrivalDate; @ApiModelProperty(value = "供应科") private String supplyDept; diff --git a/bonus-modules/bonus-material/src/main/java/com/bonus/material/scrap/domain/vo/ScrapDetailsListVo.java b/bonus-modules/bonus-material/src/main/java/com/bonus/material/scrap/domain/vo/ScrapDetailsListVo.java index a138fc61..a9413365 100644 --- a/bonus-modules/bonus-material/src/main/java/com/bonus/material/scrap/domain/vo/ScrapDetailsListVo.java +++ b/bonus-modules/bonus-material/src/main/java/com/bonus/material/scrap/domain/vo/ScrapDetailsListVo.java @@ -51,7 +51,7 @@ public class ScrapDetailsListVo { private String scrapSource; /** (0自然,1人为) */ - @Excel(name = "损坏类型", readConverterExp = "0=自然损坏,1=人为损坏") + @Excel(name = "损坏类型") private String scrapType; @ApiModelProperty(value = "任务创建人昵称") diff --git a/bonus-modules/bonus-material/src/main/resources/mapper/material/back/BackApplyInfoMapper.xml b/bonus-modules/bonus-material/src/main/resources/mapper/material/back/BackApplyInfoMapper.xml index 4405491b..f7613a09 100644 --- a/bonus-modules/bonus-material/src/main/resources/mapper/material/back/BackApplyInfoMapper.xml +++ b/bonus-modules/bonus-material/src/main/resources/mapper/material/back/BackApplyInfoMapper.xml @@ -125,9 +125,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and sai.ma_id = lod.ma_id LEFT JOIN bm_agreement_info ba ON sai.agreement_id = ba.agreement_id WHERE - 1 = 1 and mm.ma_status = '2' and mm.type_id = #{typeId} + mm.ma_status = '2' AND ba.unit_id = #{unitId} AND ba.project_id = #{proId} + + and mm.type_id = #{typeId} + GROUP BY mm.ma_code @@ -150,7 +153,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" bu.unit_name AS unitName, bp.pro_id AS proId, bp.pro_name AS proName, - bai.direct_audit_by AS directAuditBy + bai.direct_audit_by AS directAuditBy, + bai.back_sign_url AS backSignUrl, + bai.back_sign_type AS backSignType FROM back_apply_info bai LEFT JOIN tm_task_agreement tta ON bai.task_id = tta.task_id @@ -303,39 +308,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + update lease_apply_info From 15e9eb85df23c66f04d5cb2d1a2c8d2cae21a028 Mon Sep 17 00:00:00 2001 From: bonus <1203338439@qq.com> Date: Sat, 21 Jun 2025 13:37:15 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=B8=9A=E5=8A=A1=E8=81=94=E7=B3=BB?= =?UTF-8?q?=E5=8D=95=E6=A8=A1=E7=89=88=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/template/yewu.docx | Bin 12961 -> 13034 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bonus-modules/bonus-material/src/main/resources/template/yewu.docx b/bonus-modules/bonus-material/src/main/resources/template/yewu.docx index cf68e69f4118e6c4989d68fa4e635aad8f24e5cf..39afca99241b4cbc158cadffd7c970362d0ca531 100644 GIT binary patch delta 6755 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