diff --git a/pom.xml b/pom.xml index dcc3e62..be4035d 100644 --- a/pom.xml +++ b/pom.xml @@ -291,7 +291,7 @@ - NewInventory + WisdomManagement org.springframework.boot diff --git a/src/main/java/com/zg/common/utils/MinioUtil.java b/src/main/java/com/zg/common/utils/MinioUtil.java index 2e1046d..cff635b 100644 --- a/src/main/java/com/zg/common/utils/MinioUtil.java +++ b/src/main/java/com/zg/common/utils/MinioUtil.java @@ -1,9 +1,6 @@ package com.zg.common.utils; -import io.minio.MinioClient; -import io.minio.PutObjectArgs; -import io.minio.MakeBucketArgs; -import io.minio.BucketExistsArgs; +import io.minio.*; import io.minio.errors.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -13,6 +10,9 @@ import javax.annotation.PostConstruct; import java.io.InputStream; import java.util.UUID; +/** + * MinIO 工具类(支持上传并设置 bucket 公共访问权限) + */ @Component public class MinioUtil { @@ -39,41 +39,72 @@ public class MinioUtil { } /** - * 上传文件到指定 bucket - * @param file 文件 + * 上传文件到指定 bucket 的指定目录(自动设置公共权限) + * + * @param file 上传的文件 * @param bucketName bucket 名称 - * @return 返回访问URL + * @param folder 目录前缀(如 "signature/") + * @return 返回公网可访问的 URL + * @throws Exception 异常 */ - public String upload(MultipartFile file, String bucketName) throws Exception { + public String upload(MultipartFile file, String bucketName, String folder) throws Exception { String originalName = file.getOriginalFilename(); String ext = originalName != null && originalName.contains(".") ? originalName.substring(originalName.lastIndexOf(".")) : ""; - String objectName = UUID.randomUUID().toString().replace("-", "") + ext; + String objectName = folder + UUID.randomUUID().toString().replace("-", "") + ext; - InputStream in = file.getInputStream(); + try (InputStream in = file.getInputStream()) { + // 如果 bucket 不存在,则创建 + boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); + if (!exists) { + minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); + } - // 自动创建 bucket(如果不存在) - boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); - if (!exists) { - minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); + // 强制设置 bucket 策略为 public-read(幂等) + String policyJson = "{\n" + + " \"Version\":\"2012-10-17\",\n" + + " \"Statement\":[\n" + + " {\n" + + " \"Effect\":\"Allow\",\n" + + " \"Principal\":{\"AWS\":\"*\"},\n" + + " \"Action\":[\"s3:GetObject\"],\n" + + " \"Resource\":[\"arn:aws:s3:::" + bucketName + "/*\"]\n" + + " }\n" + + " ]\n" + + "}"; + + minioClient.setBucketPolicy( + SetBucketPolicyArgs.builder() + .bucket(bucketName) + .config(policyJson) + .build() + ); + + // 上传文件 + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .stream(in, file.getSize(), -1) + .contentType(file.getContentType()) + .build()); } - // 上传文件 - minioClient.putObject(PutObjectArgs.builder() - .bucket(bucketName) - .object(objectName) - .stream(in, file.getSize(), -1) - .contentType(file.getContentType()) - .build()); - return endpoint + "/" + bucketName + "/" + objectName; } /** - * 上传到默认 bucket + * 上传文件到默认 bucket 根目录 */ public String upload(MultipartFile file) throws Exception { - return upload(file, defaultBucket); + return upload(file, defaultBucket, ""); } + + /** + * 上传文件到默认 bucket 指定目录 + */ + public String upload(MultipartFile file, String folder) throws Exception { + return upload(file, defaultBucket, folder); + } + } diff --git a/src/main/java/com/zg/framework/config/SecurityConfig.java b/src/main/java/com/zg/framework/config/SecurityConfig.java index f055125..7f46219 100644 --- a/src/main/java/com/zg/framework/config/SecurityConfig.java +++ b/src/main/java/com/zg/framework/config/SecurityConfig.java @@ -116,6 +116,8 @@ public class SecurityConfig "/captchaImage", "/user/**", "/query/jh/**", + "/wisdom/signature/**", + "/system/config/**", "/AutoInventory/**", "/ws/**", "/information/device/**", diff --git a/src/main/java/com/zg/project/system/controller/SysLoginController.java b/src/main/java/com/zg/project/system/controller/SysLoginController.java index 64c3c11..07346fc 100644 --- a/src/main/java/com/zg/project/system/controller/SysLoginController.java +++ b/src/main/java/com/zg/project/system/controller/SysLoginController.java @@ -2,6 +2,10 @@ package com.zg.project.system.controller; import java.util.List; import java.util.Set; + +import com.zg.framework.manager.AsyncManager; +import com.zg.framework.manager.factory.AsyncFactory; +import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -19,6 +23,8 @@ import com.zg.project.system.domain.SysMenu; import com.zg.project.system.domain.SysUser; import com.zg.project.system.service.ISysMenuService; +import javax.servlet.http.HttpServletRequest; + /** * 登录验证 * @@ -94,4 +100,27 @@ public class SysLoginController List menus = menuService.selectMenuTreeByUserId(userId); return AjaxResult.success(menuService.buildMenus(menus)); } + + + /** + * APP登出接口 + * + * @param request + * @return + */ + @ApiOperation("APP登出接口") + @PostMapping("/app/logout") + public AjaxResult appLogout(HttpServletRequest request) { + LoginUser loginUser = tokenService.getLoginUser(request); + if (loginUser != null) { + String token = loginUser.getToken(); + // 删除 Redis 中的登录用户缓存 + tokenService.delLoginUser(token); + + // 异步记录登出日志 + AsyncManager.me().execute( + AsyncFactory.recordLogininfor(loginUser.getUsername(), Constants.LOGOUT, "APP退出成功")); + } + return AjaxResult.success("APP退出成功"); + } } diff --git a/src/main/java/com/zg/project/wisdom/controller/AuditSignatureController.java b/src/main/java/com/zg/project/wisdom/controller/AuditSignatureController.java index 47b57a2..2c4c225 100644 --- a/src/main/java/com/zg/project/wisdom/controller/AuditSignatureController.java +++ b/src/main/java/com/zg/project/wisdom/controller/AuditSignatureController.java @@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletResponse; import com.zg.common.exception.ServiceException; import com.zg.common.utils.MinioUtil; import com.zg.common.utils.SecurityUtils; +import com.zg.project.wisdom.domain.vo.AuditSignatureReviewVO; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -40,35 +41,39 @@ public class AuditSignatureController extends BaseController * 上传签字图片到 MinIO */ @PostMapping("/upload") - public AjaxResult uploadSignatures(@RequestParam("files") MultipartFile[] files) { - if (files == null || files.length == 0) { + public AjaxResult uploadSignature(@RequestParam("file") MultipartFile file) { + if (file == null || file.isEmpty()) { return AjaxResult.error("上传文件不能为空"); } - - List urls = new ArrayList<>(); - for (MultipartFile file : files) { - if (file != null && !file.isEmpty()) { - try { - String url = minioUtil.upload(file, "signature/"); - urls.add(url); - } catch (Exception e) { - return AjaxResult.error("上传失败: " + e.getMessage()); - } - } + try { + String url = minioUtil.upload(file, "jaz", "signature/"); + return AjaxResult.success("上传成功").put("url", url); + } catch (Exception e) { + return AjaxResult.error("上传失败: " + e.getMessage()); } - - return AjaxResult.success("上传成功").put("urls", urls); } /** * 查询审批记录列表 */ - @PreAuthorize("@ss.hasPermi('wisdom:signature:list')") +// @PreAuthorize("@ss.hasPermi('wisdom:signature:list')") @GetMapping("/list") - public TableDataInfo list(AuditSignature auditSignature) + public TableDataInfo list(AuditSignature auditSignature) { + startPage(); + List list = auditSignatureService.selectAuditSignatureReviewList(auditSignature); + return getDataTable(list); + } + + /** + * 查询个人提交审批记录 + */ +// @PreAuthorize("@ss.hasPermi('wisdom:signature:list')") + @GetMapping("/user/list") + public TableDataInfo listMySubmitRecords(AuditSignature auditSignature) { startPage(); - List list = auditSignatureService.selectAuditSignatureList(auditSignature); + auditSignature.setSignerId(SecurityUtils.getUserId().toString()); // 当前用户 + List list = auditSignatureService.selectMySubmittedAuditList(auditSignature); return getDataTable(list); } @@ -107,14 +112,13 @@ public class AuditSignatureController extends BaseController } /** - * 修改审批记录 + * 审批 */ @PreAuthorize("@ss.hasPermi('wisdom:signature:edit')") @Log(title = "审批记录", businessType = BusinessType.UPDATE) @PutMapping - public AjaxResult edit(@RequestBody AuditSignature auditSignature) - { - return toAjax(auditSignatureService.updateAuditSignature(auditSignature)); + public AjaxResult approve(@RequestBody AuditSignature auditSignature) { + return toAjax(auditSignatureService.approveAuditSignature(auditSignature)); } /** diff --git a/src/main/java/com/zg/project/wisdom/domain/AuditSignature.java b/src/main/java/com/zg/project/wisdom/domain/AuditSignature.java index 202ab73..8fde489 100644 --- a/src/main/java/com/zg/project/wisdom/domain/AuditSignature.java +++ b/src/main/java/com/zg/project/wisdom/domain/AuditSignature.java @@ -22,6 +22,10 @@ public class AuditSignature extends BaseEntity { @Excel(name = "单据编号") private String billNo; + /** 入库记录ID(物理外键,绑定rk_info.id) */ + @Excel(name = "入库记录ID") + private Long rkId; + /** 单据类型(0入库 1出库) */ @Excel(name = "单据类型") private String billType; @@ -96,6 +100,14 @@ public class AuditSignature extends BaseEntity { this.billNo = billNo; } + public Long getRkId() { + return rkId; + } + + public void setRkId(Long rkId) { + this.rkId = rkId; + } + public String getBillType() { return billType; } @@ -215,6 +227,7 @@ public class AuditSignature extends BaseEntity { return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) .append("id", getId()) .append("billNo", getBillNo()) + .append("rkId", getRkId()) .append("billType", getBillType()) .append("signerId", getSignerId()) .append("approverId", getApproverId()) diff --git a/src/main/java/com/zg/project/wisdom/domain/RkInfo.java b/src/main/java/com/zg/project/wisdom/domain/RkInfo.java index f4304da..b8b0a73 100644 --- a/src/main/java/com/zg/project/wisdom/domain/RkInfo.java +++ b/src/main/java/com/zg/project/wisdom/domain/RkInfo.java @@ -162,6 +162,10 @@ public class RkInfo extends BaseEntity @Excel(name = "实物ID") private String entityId; + /** 一货一图 - 货物照片URL */ + @TableField(exist = false) + private String photoUrl; + @Excel(name = "出库理货员") private String ckLihuoY; @@ -193,6 +197,18 @@ public class RkInfo extends BaseEntity @Excel(name = "是否借料", readConverterExp = "0=否,1=是") private String isBorrowed; + /** 签字图片URL(image_type = 0) */ + @TableField(exist = false) + private String signImageUrl; + + /** 现场图片URL(image_type = 1) */ + @TableField(exist = false) + private String scenePhotoUrl; + + /** 当前审批结果(0:通过,1:驳回) */ + @TableField(exist = false) + private String auditResult; + /** 入库开始时间 */ private Date startTime; @@ -283,6 +299,13 @@ public class RkInfo extends BaseEntity public void setTrayCode(String trayCode) { this.trayCode = trayCode; } public String getEntityId() { return entityId; } public void setEntityId(String entityId) { this.entityId = entityId; } + public String getPhotoUrl() { + return photoUrl; + } + + public void setPhotoUrl(String photoUrl) { + this.photoUrl = photoUrl; + } public String getCkLihuoY() { return ckLihuoY; } public void setCkLihuoY(String ckLihuoY) { this.ckLihuoY = ckLihuoY; } public String getCkType() { return ckType; } @@ -341,6 +364,29 @@ public class RkInfo extends BaseEntity this.isBorrowed = isBorrowed; } + public String getSignImageUrl() { + return signImageUrl; + } + + public void setSignImageUrl(String signImageUrl) { + this.signImageUrl = signImageUrl; + } + + public String getScenePhotoUrl() { + return scenePhotoUrl; + } + + public void setScenePhotoUrl(String scenePhotoUrl) { + this.scenePhotoUrl = scenePhotoUrl; + } + + public String getAuditResult() { + return auditResult; + } + + public void setAuditResult(String auditResult) { + this.auditResult = auditResult; + } public String getIsDelete() { return isDelete; } public void setIsDelete(String isDelete) { this.isDelete = isDelete; } @@ -378,6 +424,7 @@ public class RkInfo extends BaseEntity .append("pcodeId", getPcodeId()) .append("trayCode", getTrayCode()) .append("entityId", getEntityId()) + .append("photoUrl", getPhotoUrl()) .append("createBy", getCreateBy()) .append("createTime", getCreateTime()) .append("updateBy", getUpdateBy()) @@ -396,6 +443,9 @@ public class RkInfo extends BaseEntity .append("startTime", getStartTime()) .append("endTime", getEndTime()) .append("isBorrowed", getIsBorrowed()) + .append("signImageUrl", getSignImageUrl()) + .append("scenePhotoUrl", getScenePhotoUrl()) + .append("auditResult", getAuditResult()) .append("isDelete", getIsDelete()) .toString(); } diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/PcRkInfoBatchDTO.java b/src/main/java/com/zg/project/wisdom/domain/dto/PcRkInfoBatchDTO.java index 2133a2d..396f21c 100644 --- a/src/main/java/com/zg/project/wisdom/domain/dto/PcRkInfoBatchDTO.java +++ b/src/main/java/com/zg/project/wisdom/domain/dto/PcRkInfoBatchDTO.java @@ -34,7 +34,5 @@ public class PcRkInfoBatchDTO { /** 发起人签字图片 URL(单张) */ private String signatureUrl; - /** 现场照片 URL 列表(多张) */ - private List photoUrls; } diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/PcRkInfoItemDTO.java b/src/main/java/com/zg/project/wisdom/domain/dto/PcRkInfoItemDTO.java index 0448aa0..4f583d8 100644 --- a/src/main/java/com/zg/project/wisdom/domain/dto/PcRkInfoItemDTO.java +++ b/src/main/java/com/zg/project/wisdom/domain/dto/PcRkInfoItemDTO.java @@ -1,10 +1,13 @@ package com.zg.project.wisdom.domain.dto; +import lombok.Data; + import java.math.BigDecimal; /** * PC端 - 入库明细 DTO(字段驼峰命名规范) */ +@Data public class PcRkInfoItemDTO { /** 县局 */ @@ -73,181 +76,7 @@ public class PcRkInfoItemDTO { /** 备注 */ private String remark; - // ======= Getter / Setter ======= + /** 单条货物对应的现场照片 URL */ + private String photoUrl; - public String getXj() { - return xj; - } - - public void setXj(String xj) { - this.xj = xj; - } - - public Long getGysJhId() { - return gysJhId; - } - - public void setGysJhId(Long gysJhId) { - this.gysJhId = gysJhId; - } - - public String getWlNo() { - return wlNo; - } - - public void setWlNo(String wlNo) { - this.wlNo = wlNo; - } - - public String getWlMs() { - return wlMs; - } - - public void setWlMs(String wlMs) { - this.wlMs = wlMs; - } - - public String getXmMs() { - return xmMs; - } - - public void setXmMs(String xmMs) { - this.xmMs = xmMs; - } - - public String getXmNo() { - return xmNo; - } - - public void setXmNo(String xmNo) { - this.xmNo = xmNo; - } - - public String getSapWlNo() { - return sapWlNo; - } - - public void setSapWlNo(String sapWlNo) { - this.sapWlNo = sapWlNo; - } - - public String getSapWlMs() { - return sapWlMs; - } - - public void setSapWlMs(String sapWlMs) { - this.sapWlMs = sapWlMs; - } - - public String getGysNo() { - return gysNo; - } - - public void setGysNo(String gysNo) { - this.gysNo = gysNo; - } - - public String getGysMc() { - return gysMc; - } - - public void setGysMc(String gysMc) { - this.gysMc = gysMc; - } - - public String getSapNo() { - return sapNo; - } - - public void setSapNo(String sapNo) { - this.sapNo = sapNo; - } - - public Long getJhQty() { - return jhQty; - } - - public void setJhQty(Long jhQty) { - this.jhQty = jhQty; - } - - public Long getHtQty() { - return htQty; - } - - public void setHtQty(Long htQty) { - this.htQty = htQty; - } - - public String getDw() { - return dw; - } - - public void setDw(String dw) { - this.dw = dw; - } - - public BigDecimal getJhAmt() { - return jhAmt; - } - - public void setJhAmt(BigDecimal jhAmt) { - this.jhAmt = jhAmt; - } - - public BigDecimal getHtDj() { - return htDj; - } - - public void setHtDj(BigDecimal htDj) { - this.htDj = htDj; - } - - public BigDecimal getRealQty() { - return realQty; - } - - public void setRealQty(BigDecimal realQty) { - this.realQty = realQty; - } - - public String getPcode() { - return pcode; - } - - public void setPcode(String pcode) { - this.pcode = pcode; - } - - public String getPcodeId() { - return pcodeId; - } - - public void setPcodeId(String pcodeId) { - this.pcodeId = pcodeId; - } - - public String getTrayCode() { - return trayCode; - } - - public void setTrayCode(String trayCode) { - this.trayCode = trayCode; - } - - public String getEntityId() { - return entityId; - } - - public void setEntityId(String entityId) { - this.entityId = entityId; - } - - public String getRemark() { - return remark; - } - - public void setRemark(String remark) { - this.remark = remark; - } } diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoBatchDTO.java b/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoBatchDTO.java index 1abd9cd..c2da9f5 100644 --- a/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoBatchDTO.java +++ b/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoBatchDTO.java @@ -27,6 +27,4 @@ public class RkInfoBatchDTO { /** 发起人签字图片 URL(单张) */ private String signatureUrl; - /** 现场照片 URL 列表(多张) */ - private List photoUrls; } diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoItemDTO.java b/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoItemDTO.java index 68167a6..8f764a3 100644 --- a/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoItemDTO.java +++ b/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoItemDTO.java @@ -1,11 +1,14 @@ package com.zg.project.wisdom.domain.dto; +import lombok.Data; + import java.math.BigDecimal; import java.util.List; /** * APP端 - 入库明细 DTO */ +@Data public class RkInfoItemDTO { /** 供应计划主键ID */ @@ -52,124 +55,4 @@ public class RkInfoItemDTO { /** 实物扫码记录列表 */ private List scanList; - - public Long getGysJhId() { - return gysJhId; - } - - public void setGysJhId(Long gysJhId) { - this.gysJhId = gysJhId; - } - - public String getWlNo() { - return wlNo; - } - - public void setWlNo(String wlNo) { - this.wlNo = wlNo; - } - - public String getWlMs() { - return wlMs; - } - - public void setWlMs(String wlMs) { - this.wlMs = wlMs; - } - - public String getXmNo() { - return xmNo; - } - - public void setXmNo(String xmNo) { - this.xmNo = xmNo; - } - - public String getXmMs() { - return xmMs; - } - - public void setXmMs(String xmMs) { - this.xmMs = xmMs; - } - - public String getXj() { - return xj; - } - - public void setXj(String xj) { - this.xj = xj; - } - - public String getGysNo() { - return gysNo; - } - - public void setGysNo(String gysNo) { - this.gysNo = gysNo; - } - - public String getGysMc() { - return gysMc; - } - - public void setGysMc(String gysMc) { - this.gysMc = gysMc; - } - - public String getSapNo() { - return sapNo; - } - - public void setSapNo(String sapNo) { - this.sapNo = sapNo; - } - - public Long getJhQty() { - return jhQty; - } - - public void setJhQty(Long jhQty) { - this.jhQty = jhQty; - } - - public Long getHtQty() { - return htQty; - } - - public void setHtQty(Long htQty) { - this.htQty = htQty; - } - - public String getDw() { - return dw; - } - - public void setDw(String dw) { - this.dw = dw; - } - - public BigDecimal getJhAmt() { - return jhAmt; - } - - public void setJhAmt(BigDecimal jhAmt) { - this.jhAmt = jhAmt; - } - - public BigDecimal getHtDj() { - return htDj; - } - - public void setHtDj(BigDecimal htDj) { - this.htDj = htDj; - } - - public List getScanList() { - return scanList; - } - - public void setScanList(List scanList) { - this.scanList = scanList; - } } diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoScanDTO.java b/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoScanDTO.java index 88d3e9c..48c7987 100644 --- a/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoScanDTO.java +++ b/src/main/java/com/zg/project/wisdom/domain/dto/RkInfoScanDTO.java @@ -1,7 +1,9 @@ package com.zg.project.wisdom.domain.dto; -import java.math.BigDecimal; +import lombok.Data; +import java.math.BigDecimal; +@Data public class RkInfoScanDTO { /** 库位码 */ @@ -19,54 +21,9 @@ public class RkInfoScanDTO { /** 实物 ID */ private String entityId; + /** 现场照片URL(单张) */ + private String photoUrl; + /** 备注 */ private String remark; - - public String getPcode() { - return pcode; - } - - public void setPcode(String pcode) { - this.pcode = pcode; - } - - public String getPcodeId() { - return pcodeId; - } - - public void setPcodeId(String pcodeId) { - this.pcodeId = pcodeId; - } - - public String getTrayCode() { - return trayCode; - } - - public void setTrayCode(String trayCode) { - this.trayCode = trayCode; - } - - public BigDecimal getRealQty() { - return realQty; - } - - public void setRealQty(BigDecimal realQty) { - this.realQty = realQty; - } - - public String getEntityId() { - return entityId; - } - - public void setEntityId(String entityId) { - this.entityId = entityId; - } - - public String getRemark() { - return remark; - } - - public void setRemark(String remark) { - this.remark = remark; - } } diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureReviewVO.java b/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureReviewVO.java new file mode 100644 index 0000000..915fd12 --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureReviewVO.java @@ -0,0 +1,75 @@ +package com.zg.project.wisdom.domain.vo; + +import com.zg.project.wisdom.domain.AuditSignature; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 审核记录封装VO(包含一条审核记录 + 多张现场照片) + */ +@Data +public class AuditSignatureReviewVO { + + /** 主键ID(审核记录的ID) */ + private Long id; + + /** 单据编号 */ + private String billNo; + + /** 入库记录ID(对应rk_info.id) */ + private Long rkId; + + /** 单据类型(0入库,1出库) */ + private String billType; + + /** 审核人ID */ + private String approverId; + + /** 审核人签字图片URL(签字图) */ + private String approverSignUrl; + + /** 审核结果(0通过,1驳回) */ + private String auditResult; + + /** 是否当前记录(1是,0否) */ + private String isCurrent; + + /** 审核时间 */ + private Date signTime; + + /** 审核备注 */ + private String remark; + + /** 创建人 */ + private String createBy; + + /** 创建时间 */ + private Date createTime; + + /** 更新人 */ + private String updateBy; + + /** 更新时间 */ + private Date updateTime; + + /** 逻辑删除标记(0正常,1删除) */ + private String isDelete; + + /** 携带入库信息的现场图片列表 */ + private List scenePhotos; + + /** 入库类型名称(中文) */ + private String rkTypeName; + + /** 所属仓库名称(中文) */ + private String cangkuName; + + /** 物资类型名称(中文) */ + private String wlTypeName; + + /** 理货员名称(原本就是中文) */ + private String lihuoY; + +} diff --git a/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureVo.java b/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureVo.java new file mode 100644 index 0000000..810946d --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/domain/vo/AuditSignatureVo.java @@ -0,0 +1,42 @@ +package com.zg.project.wisdom.domain.vo; + +import com.zg.project.wisdom.domain.AuditSignature; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; + +/** + * 签字记录 + 入库货物信息 展示用 VO + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class AuditSignatureVo extends AuditSignature { + + /** 项目号 */ + private String xmNo; + + /** 项目描述 */ + private String xmMs; + + /** 物料描述 */ + private String wlMs; + + /** 供应商名称 */ + private String gysMc; + + /** 物料号 */ + private String wlNo; + + /** 实际入库数量 */ + private BigDecimal realQty; + + /** 计量单位 */ + private String dw; + + /** 库位码(覆盖 a.pcode,改为取 r.pcode) */ + private String pcode; + + /** 入库备注(rk_info 表里的) */ + private String rkRemark; +} diff --git a/src/main/java/com/zg/project/wisdom/mapper/AuditSignatureMapper.java b/src/main/java/com/zg/project/wisdom/mapper/AuditSignatureMapper.java index bd6d9ea..75602a0 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/AuditSignatureMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/AuditSignatureMapper.java @@ -2,6 +2,8 @@ package com.zg.project.wisdom.mapper; import java.util.List; import com.zg.project.wisdom.domain.AuditSignature; +import com.zg.project.wisdom.domain.vo.AuditSignatureVo; +import org.apache.ibatis.annotations.Param; /** * 审批记录Mapper接口 @@ -71,7 +73,7 @@ public interface AuditSignatureMapper * @param * @return */ - boolean existsCurrentSigner(String billNo, String number); + boolean existsCurrentSigner(@Param("billNo") String billNo, @Param("signerRole") String signerRole); /** * 修改当前申请数据的可用状态 @@ -86,4 +88,32 @@ public interface AuditSignatureMapper * @return */ void batchInsert(List recordList); + + /** + * 查询现场图片URL(按入库ID) + */ + AuditSignature selectPhotoUrlByRkId(@Param("rkId") Long rkId); + + /** + * 查询审批记录列表(按主表ID) + */ + List selectAuditMainList(AuditSignature filter); + + /** + * 获取包含入库货物信息的现场图记录 + */ + List selectScenePhotosWithGoodsByBillNo(@Param("billNo") String billNo); + + /** + * 获取提交人列表 + */ + List selectAuditMainListBySubmitter(AuditSignature filter); + + /** + * 审核 + * @param auditSignature + * @return + */ + int approveAuditByBillNo(AuditSignature auditSignature); + } diff --git a/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java b/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java index acccc2d..4998e1d 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java @@ -1,5 +1,6 @@ package com.zg.project.wisdom.mapper; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -176,4 +177,10 @@ public interface RkInfoMapper * 修改入库单据状态 */ int updateStatusByBillNo(RkInfo rkInfo); + + /** + * 查询每个 billNo 对应的一条入库记录(用于获取公共字段) + */ + List selectOneForEachBillNo(@Param("billNos") List billNos); + } diff --git a/src/main/java/com/zg/project/wisdom/service/IAuditSignatureService.java b/src/main/java/com/zg/project/wisdom/service/IAuditSignatureService.java index 48be783..c1e80ff 100644 --- a/src/main/java/com/zg/project/wisdom/service/IAuditSignatureService.java +++ b/src/main/java/com/zg/project/wisdom/service/IAuditSignatureService.java @@ -2,6 +2,7 @@ package com.zg.project.wisdom.service; import java.util.List; import com.zg.project.wisdom.domain.AuditSignature; +import com.zg.project.wisdom.domain.vo.AuditSignatureReviewVO; /** * 审批记录Service接口 @@ -71,4 +72,27 @@ public interface IAuditSignatureService * @param audit */ void audit(AuditSignature audit); + + /** + * 查询审批记录列表 + * + * @param auditSignature 审批记录 + * @return 审批记录集合 + */ + List selectAuditSignatureReviewList(AuditSignature auditSignature); + + /** + * 查询我提交的审批列表 + * + * @param auditSignature 审批记录 + * @return 审批记录集合 + */ + List selectMySubmittedAuditList(AuditSignature auditSignature); + + /** + * 审批 + * @param auditSignature + * @return + */ + int approveAuditSignature(AuditSignature auditSignature); } diff --git a/src/main/java/com/zg/project/wisdom/service/impl/AuditSignatureServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/AuditSignatureServiceImpl.java index ae0ff02..8649b88 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/AuditSignatureServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/AuditSignatureServiceImpl.java @@ -1,13 +1,19 @@ package com.zg.project.wisdom.service.impl; -import java.util.List; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; import com.zg.common.exception.ServiceException; import com.zg.common.utils.DateUtils; import com.zg.common.utils.SecurityUtils; +import com.zg.common.utils.StringUtils; import com.zg.project.wisdom.domain.RkInfo; +import com.zg.project.wisdom.domain.vo.AuditSignatureReviewVO; +import com.zg.project.wisdom.domain.vo.AuditSignatureVo; import com.zg.project.wisdom.mapper.RkInfoMapper; import org.apache.ibatis.annotations.Param; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zg.project.wisdom.mapper.AuditSignatureMapper; @@ -153,4 +159,78 @@ public class AuditSignatureServiceImpl implements IAuditSignatureService rkInfoMapper.updateStatusByBillNo(rk); } + @Override + public List selectAuditSignatureReviewList(AuditSignature filter) { + + // 1. 查询主记录列表(发起人签字图) + List mainList = auditSignatureMapper.selectAuditMainList(filter); + + // ✅ 批量提取所有 billNo + Set billNoSet = mainList.stream() + .map(AuditSignature::getBillNo) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toSet()); + + // 2. 一次性查询所有 billNo 对应的入库公共字段 + Map rkInfoMap = new HashMap<>(); + if (!billNoSet.isEmpty()) { + List rkInfoList = rkInfoMapper.selectOneForEachBillNo(new ArrayList<>(billNoSet)); + rkInfoMap = rkInfoList.stream() + .collect(Collectors.toMap(RkInfo::getBillNo, Function.identity(), (a, b) -> a)); + } + + // 3. 构造返回结果列表 + List resultList = new ArrayList<>(); + for (AuditSignature main : mainList) { + AuditSignatureReviewVO vo = new AuditSignatureReviewVO(); + BeanUtils.copyProperties(main, vo); + + // 设置入库公共字段(若存在) + RkInfo rk = rkInfoMap.get(main.getBillNo()); + if (rk != null) { + vo.setRkTypeName(rk.getRkTypeName()); + vo.setCangkuName(rk.getCangkuName()); + vo.setWlTypeName(rk.getWlTypeName()); + vo.setLihuoY(rk.getLihuoY()); + } + + // 查询该 billNo 下的现场照片 + 入库字段 + List photoList = auditSignatureMapper.selectScenePhotosWithGoodsByBillNo(main.getBillNo()); + vo.setScenePhotos(photoList); + + resultList.add(vo); + } + + return resultList; + } + + + @Override + public List selectMySubmittedAuditList(AuditSignature filter) { + // 查询发起人/现场拍照图中主图(image_type = 0)记录 + List mainList = auditSignatureMapper.selectAuditMainListBySubmitter(filter); + + List resultList = new ArrayList<>(); + for (AuditSignature main : mainList) { + AuditSignatureReviewVO vo = new AuditSignatureReviewVO(); + BeanUtils.copyProperties(main, vo); + + // 查询现场图(包含货物信息) + String billNo = main.getBillNo(); + List scenePhotos = auditSignatureMapper.selectScenePhotosWithGoodsByBillNo(billNo); + vo.setScenePhotos(scenePhotos); + + resultList.add(vo); + } + + return resultList; + } + + @Override + public int approveAuditSignature(AuditSignature auditSignature) { + auditSignature.setUpdateTime(DateUtils.getNowDate()); + auditSignature.setSignerRole("1"); // 审核人 + auditSignature.setIsCurrent("1"); // 当前记录 + return auditSignatureMapper.approveAuditByBillNo(auditSignature); + } } diff --git a/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java index da80c00..39a3a07 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java @@ -10,6 +10,7 @@ import java.util.stream.Collectors; import com.zg.common.exception.ServiceException; import com.zg.common.utils.DateUtils; import com.zg.common.utils.SecurityUtils; +import com.zg.common.utils.StringUtils; import com.zg.project.Inventory.AutoInventory.mapper.InventoryMatchScanMapper; import com.zg.project.Inventory.Task.mapper.InventoryTaskMapper; import com.zg.project.Inventory.domain.dto.QueryDTO; @@ -79,10 +80,13 @@ public class RkInfoServiceImpl implements IRkInfoService */ @Override public List selectRkInfoList(RkInfo rkInfo) { + boolean needAudit = "1".equals(configService.selectConfigByKey("rk.audit.enabled")); + List list = rkInfoMapper.selectRkInfoList(rkInfo); LocalDate today = LocalDate.now(); for (RkInfo info : list) { + // 计算库龄 if (info.getRkTime() != null) { LocalDate rkDate = info.getRkTime().toInstant() .atZone(ZoneId.systemDefault()) @@ -90,12 +94,28 @@ public class RkInfoServiceImpl implements IRkInfoService long days = ChronoUnit.DAYS.between(rkDate, today); info.setStockAge(days); } + + // 查询现场图片 + 审核结果(image_type = '1') + AuditSignature signature = auditSignatureMapper.selectPhotoUrlByRkId(info.getId()); + if (signature != null) { + info.setScenePhotoUrl(signature.getSignUrl()); + info.setAuditResult(signature.getAuditResult()); + } else { + info.setScenePhotoUrl(null); + info.setAuditResult(null); + } + } + + // 审核开启,过滤掉未通过的(只有 auditResult = '0' 保留) + if (needAudit) { + list = list.stream() + .filter(info -> "0".equals(info.getAuditResult())) + .collect(Collectors.toList()); } return list; } - /** * 修改库存单据主 * @@ -145,10 +165,13 @@ public class RkInfoServiceImpl implements IRkInfoService List list = dto.getRkList(); List rkInfos = new ArrayList<>(); - boolean needAudit = "1".equals(configService.selectConfigByKey("stock.audit.enabled")); + boolean needAudit = "1".equals(configService.selectConfigByKey("rk.audit.enabled")); String userId = SecurityUtils.getUserId().toString(); Date now = DateUtils.getNowDate(); + List records = new ArrayList<>(); + + // ✅ 第一步:先构造 RkInfo 列表(不保存照片) for (PcRkInfoItemDTO item : list) { RkInfo rk = new RkInfo(); BeanUtils.copyProperties(item, rk); @@ -156,10 +179,12 @@ public class RkInfoServiceImpl implements IRkInfoService rk.setRkType(dto.getRkType()); rk.setWlType(dto.getWlType()); rk.setLihuoY(dto.getLihuoY()); + rk.setRkTime(now); rk.setCangku(dto.getCangku()); rk.setCreateBy(userId); rk.setCreateTime(now); rk.setIsDelete("0"); + if (needAudit) { rk.setStatus("0"); // 入库待审核 rk.setIsChuku("2"); // 待入库(审核中) @@ -167,60 +192,64 @@ public class RkInfoServiceImpl implements IRkInfoService rk.setStatus("1"); // 审核通过 rk.setIsChuku("0"); // 已入库 } + rkInfos.add(rk); } + // ✅ 第二步:批量保存入库记录,回填主键 ID rkInfoMapper.batchInsertRkInfo(rkInfos); - // ====== 写入签字记录(支持重新提交)====== - if (needAudit) { - List records = new ArrayList<>(); + // ✅ 第三步:根据主键构造照片记录 + for (int i = 0; i < rkInfos.size(); i++) { + RkInfo rk = rkInfos.get(i); + PcRkInfoItemDTO item = list.get(i); + if (needAudit && StringUtils.isNotBlank(item.getPhotoUrl())) { + AuditSignature photo = new AuditSignature(); + photo.setRkId(rk.getId()); // ✅ 此时已填充 ID + photo.setBillNo(billNo); + photo.setBillType("0"); + photo.setAuditResult("2"); + photo.setSignerId(userId); + photo.setSignerRole("2"); // 拍照人 + photo.setImageType("1"); // 现场图 + photo.setSignUrl(item.getPhotoUrl()); + photo.setSignTime(now); + photo.setPcode(item.getPcode()); + photo.setTrayCode(item.getTrayCode()); + photo.setApproverId(dto.getApproverId()); + photo.setIsCurrent("1"); + photo.setIsDelete("0"); + photo.setCreateBy(userId); + photo.setCreateTime(now); + records.add(photo); + } + } + + // ✅ 第四步:如果启用审核,添加发起人签字记录 + if (needAudit) { // === 检查是否已有发起人签字记录 === - boolean hasOldSign = auditSignatureMapper.existsCurrentSigner(billNo, "0"); // signerRole = 0 表示发起人 + boolean hasOldSign = auditSignatureMapper.existsCurrentSigner(billNo, "0"); if (hasOldSign) { - // 将旧记录设为历史 auditSignatureMapper.updateIsCurrentToZero(billNo, "0"); } - // === 新的主签字记录(发起人 + 审批人) === AuditSignature mainSign = new AuditSignature(); - mainSign.setBillNo(billNo); // 单据号 - mainSign.setBillType("0"); // 单据类型(0:入库) - mainSign.setSignerId(userId); // 签字人ID(发起人) - mainSign.setSignerRole("0"); // 角色(0:发起人) - mainSign.setApproverId(dto.getApproverId()); // 审批人ID - mainSign.setSignUrl(dto.getSignatureUrl()); // 发起人签字图片URL - mainSign.setImageType("0"); // 图片类型(0:签字) - mainSign.setSignTime(now); // 签字时间 - mainSign.setIsCurrent("1"); // 当前记录 - mainSign.setIsDelete("0"); // 是否删除 - mainSign.setCreateBy(userId); // 创建人 - mainSign.setCreateTime(now); // 创建时间 + mainSign.setBillNo(billNo); + mainSign.setBillType("0"); + mainSign.setSignerId(userId); + mainSign.setSignerRole("0"); // 发起人 + mainSign.setApproverId(dto.getApproverId()); + mainSign.setSignUrl(dto.getSignatureUrl()); + mainSign.setImageType("0"); // 签字图 + mainSign.setSignTime(now); + mainSign.setIsCurrent("1"); + mainSign.setIsDelete("0"); + mainSign.setCreateBy(userId); + mainSign.setCreateTime(now); records.add(mainSign); - // === 现场照片(每张一条记录) === - if (dto.getPhotoUrls() != null && !dto.getPhotoUrls().isEmpty()) { - for (String url : dto.getPhotoUrls()) { - if (url == null || url.trim().isEmpty()) continue; - - AuditSignature photo = new AuditSignature(); - photo.setBillNo(billNo); - photo.setBillType("0"); - photo.setSignerId(userId); - photo.setSignerRole("2"); // 拍照人 - photo.setImageType("1"); // 现场图片 - photo.setApproverId(dto.getApproverId()); - photo.setSignUrl(url); - photo.setSignTime(now); - photo.setIsCurrent("1"); - photo.setIsDelete("0"); - photo.setCreateBy(userId); - photo.setCreateTime(now); - records.add(photo); - } - } - + // ✅ 写入照片 + 签字图 if (!records.isEmpty()) { auditSignatureMapper.batchInsert(records); } @@ -232,7 +261,6 @@ public class RkInfoServiceImpl implements IRkInfoService } } - /** * 新增入库单据(APP) * @param dto @@ -249,57 +277,58 @@ public class RkInfoServiceImpl implements IRkInfoService throw new ServiceException("rkList 入库明细列表不能为空"); } - boolean needAudit = "1".equals(configService.selectConfigByKey("stock.audit.enabled")); - String billNo = BillNoUtil.generateTodayBillNo("CK"); + boolean needAudit = "1".equals(configService.selectConfigByKey("rk.audit.enabled")); + String billNo = BillNoUtil.generateTodayBillNo("RK"); + // ✅ 第一步:构造入库数据列表 for (RkInfoItemDTO item : dto.getRkList()) { List scanList = item.getScanList(); if (scanList == null || scanList.isEmpty()) continue; for (RkInfoScanDTO scan : scanList) { RkInfo entity = new RkInfo(); - entity.setRkType(dto.getRkType()); // 入库类型 - entity.setWlType(dto.getWlType()); // 物资类型 - entity.setCangku(dto.getCangku()); // 所属仓库ID - entity.setLihuoY(dto.getLihuoY()); // 理货员 - entity.setBillNo(billNo); // 单据号(统一生成) - entity.setXj(item.getXj()); // 县局 - entity.setXmMs(item.getXmMs()); // 项目描述 - entity.setXmNo(item.getXmNo()); // 项目编号 - entity.setSapNo(item.getSapNo()); // SAP订单编号 - entity.setJhQty(item.getJhQty()); // 计划交货数量 - entity.setHtQty(item.getHtQty()); // 合同数量 - entity.setJhAmt(item.getJhAmt()); // 计划交货金额 - entity.setHtDj(item.getHtDj()); // 合同单价 - entity.setDw(item.getDw()); // 计量单位 - entity.setWlNo(item.getWlNo()); // 物料号 - entity.setWlMs(item.getWlMs()); // 物料描述 - entity.setGysNo(item.getGysNo()); // 供应商编号 - entity.setGysMc(item.getGysMc()); // 供应商名称 - entity.setPcode(scan.getPcode()); // 库位码(明细) - entity.setPcodeId(CodeConvertUtil.stringToHex(scan.getPcode())); // 库位码(16进制编码) - entity.setTrayCode(scan.getTrayCode()); // 托盘码 - entity.setRealQty(scan.getRealQty()); // 实际入库数量 - entity.setEntityId(scan.getEntityId()); // 实物ID - entity.setRemark(scan.getRemark()); // 备注 - entity.setIsDelete("0"); // 是否删除(0=正常) - entity.setIsChuku("0"); // 是否已出库(0=否) + entity.setRkType(dto.getRkType()); + entity.setWlType(dto.getWlType()); + entity.setCangku(dto.getCangku()); + entity.setLihuoY(dto.getLihuoY()); + entity.setBillNo(billNo); + entity.setXj(item.getXj()); + entity.setXmMs(item.getXmMs()); + entity.setXmNo(item.getXmNo()); + entity.setSapNo(item.getSapNo()); + entity.setJhQty(item.getJhQty()); + entity.setHtQty(item.getHtQty()); + entity.setJhAmt(item.getJhAmt()); + entity.setHtDj(item.getHtDj()); + entity.setDw(item.getDw()); + entity.setWlNo(item.getWlNo()); + entity.setWlMs(item.getWlMs()); + entity.setGysNo(item.getGysNo()); + entity.setGysMc(item.getGysMc()); + entity.setPcode(scan.getPcode()); + entity.setPcodeId(CodeConvertUtil.stringToHex(scan.getPcode())); + entity.setTrayCode(scan.getTrayCode()); + entity.setRealQty(scan.getRealQty()); + entity.setEntityId(scan.getEntityId()); + entity.setRemark(scan.getRemark()); + entity.setIsDelete("0"); + entity.setRkTime(now); + entity.setCreateBy(userId); + entity.setCreateTime(now); + if (needAudit) { - entity.setStatus("0"); // 入库待审核 - entity.setIsChuku("3"); // 待入库(审核中) + entity.setStatus("0"); // 待审核 + entity.setIsChuku("3"); // 待入库(审核中) } else { - entity.setStatus("1"); // 审核通过 - entity.setIsChuku("0"); // 已入库 + entity.setStatus("1"); // 审核通过 + entity.setIsChuku("0"); // 已入库 } - entity.setRkTime(now); // 入库时间 - entity.setCreateBy(userId); // 创建人 - entity.setCreateTime(now); // 创建时间 saveList.add(entity); } if (item.getGysJhId() != null) { - gysJhMapper.updateStatusById(item.getGysJhId()); // 更新供应计划状态 + gysJhMapper.updateStatusById(item.getGysJhId()); } } @@ -307,59 +336,69 @@ public class RkInfoServiceImpl implements IRkInfoService throw new ServiceException("未提取到任何可保存的数据"); } - rkInfoMapper.batchInsertRkInfo(saveList); // 批量插入入库数据 + // ✅ 第二步:批量插入入库数据,回填主键ID + rkInfoMapper.batchInsertRkInfo(saveList); - // ✅ 写入签字记录(支持重新提交) + // ✅ 第三步:处理签字与照片记录(仅启用审核时) if (needAudit) { List recordList = new ArrayList<>(); - // === 判断是否是重新提交 === + // 检查是否重新提交,旧记录置为非当前 boolean isResubmit = auditSignatureMapper.existsCurrentSigner(billNo, "0"); if (isResubmit) { - auditSignatureMapper.updateIsCurrentToZero(billNo, "0"); // 将旧签字记录置为历史 + auditSignatureMapper.updateIsCurrentToZero(billNo, "0"); } - // === 发起人签字记录 === + // ✅ 1. 添加发起人签字图记录 AuditSignature mainSign = new AuditSignature(); - mainSign.setBillNo(billNo); // 单据号 - mainSign.setBillType("0"); // 单据类型:0=入库 - mainSign.setSignerId(userId); // 签字人ID(当前登录人) - mainSign.setSignerRole("0"); // 签字人角色:0=发起人 - mainSign.setSignUrl(dto.getSignatureUrl()); // 发起人签字图片URL - mainSign.setSignTime(now); // 签字时间 - mainSign.setIsCurrent("1"); // 是否当前记录(1=当前) - mainSign.setImageType("0"); // 图片类型:0=签字图 - mainSign.setApproverId(dto.getApproverId()); // 审批人ID - mainSign.setIsDelete("0"); // 是否删除(0=否) - mainSign.setCreateBy(userId); // 创建人 - mainSign.setCreateTime(now); // 创建时间 + mainSign.setBillNo(billNo); + mainSign.setBillType("0"); + mainSign.setSignerId(userId); + mainSign.setSignerRole("0"); // 发起人 + mainSign.setSignUrl(dto.getSignatureUrl()); + mainSign.setImageType("0"); // 签字图 + mainSign.setSignTime(now); + mainSign.setApproverId(dto.getApproverId()); + mainSign.setIsCurrent("1"); + mainSign.setIsDelete("0"); + mainSign.setCreateBy(userId); + mainSign.setCreateTime(now); recordList.add(mainSign); - // === 现场照片记录 === - if (dto.getPhotoUrls() != null) { - for (String photoUrl : dto.getPhotoUrls()) { - if (photoUrl == null || photoUrl.trim().isEmpty()) continue; + // ✅ 2. 绑定每条 rkInfo 与对应 scanList 的 photoUrl + int index = 0; + for (RkInfoItemDTO item : dto.getRkList()) { + List scanList = item.getScanList(); + if (scanList == null || scanList.isEmpty()) continue; - AuditSignature photo = new AuditSignature(); - photo.setBillNo(billNo); // 单据号 - photo.setBillType("0"); // 单据类型:0=入库 - photo.setSignerId(userId); // 拍照人ID(当前登录人) - photo.setSignerRole("2"); // 签字人角色:2=拍照人 - photo.setSignUrl(photoUrl); // 现场图片URL - photo.setImageType("1"); // 图片类型:1=现场图 - photo.setSignTime(now); // 拍照时间 - photo.setApproverId(dto.getApproverId()); // 审批人ID - photo.setIsCurrent("1"); // 是否当前记录 - photo.setIsDelete("0"); // 是否删除 - photo.setCreateBy(userId); // 创建人 - photo.setCreateTime(now); // 创建时间 + for (RkInfoScanDTO scan : scanList) { + RkInfo rk = saveList.get(index++); - recordList.add(photo); + if (StringUtils.isNotBlank(scan.getPhotoUrl())) { + AuditSignature photo = new AuditSignature(); + photo.setBillNo(billNo); + photo.setBillType("0"); + photo.setRkId(rk.getId()); + photo.setSignerId(userId); + photo.setSignerRole("2"); // 拍照人 + photo.setSignUrl(scan.getPhotoUrl()); + photo.setImageType("1"); // 现场图 + photo.setSignTime(now); + photo.setApproverId(dto.getApproverId()); + photo.setIsCurrent("1"); + photo.setIsDelete("0"); + photo.setCreateBy(userId); + photo.setCreateTime(now); + photo.setPcode(rk.getPcode()); + photo.setTrayCode(rk.getTrayCode()); + recordList.add(photo); + } } } + // ✅ 3. 批量写入 audit_signature if (!recordList.isEmpty()) { - auditSignatureMapper.batchInsert(recordList); // 批量插入签字记录 + auditSignatureMapper.batchInsert(recordList); } } diff --git a/src/main/resources/application-druid.yml b/src/main/resources/application-druid.yml index d11107e..7fb4159 100644 --- a/src/main/resources/application-druid.yml +++ b/src/main/resources/application-druid.yml @@ -7,6 +7,7 @@ spring: # 主库数据源 master: url: jdbc:mysql://192.168.1.20:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +# url: jdbc:mysql://192.168.1.251:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://localhost:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: shzg diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 66e7846..8e856b6 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -69,6 +69,7 @@ spring: redis: # 地址 host: 192.168.1.20 +# host: 192.168.1.251 # host: localhost # 端口,默认为6379 port: 6379 diff --git a/src/main/resources/mybatis/wisdom/AuditSignatureMapper.xml b/src/main/resources/mybatis/wisdom/AuditSignatureMapper.xml index 87abcc0..b1a0485 100644 --- a/src/main/resources/mybatis/wisdom/AuditSignatureMapper.xml +++ b/src/main/resources/mybatis/wisdom/AuditSignatureMapper.xml @@ -3,28 +3,45 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -77,6 +94,77 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND is_delete = '0' + + + + + + + + + + insert into audit_signature @@ -136,7 +224,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" is_current, is_delete, create_by, - create_time + create_time, + rk_id ) VALUES @@ -152,7 +241,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{item.isCurrent}, #{item.isDelete}, #{item.createBy}, - #{item.createTime} + #{item.createTime}, + #{item.rkId} ) @@ -193,6 +283,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND is_delete = '0' + + UPDATE audit_signature + + audit_result = #{auditResult}, + approver_sign_url = #{approverSignUrl}, + remark = #{remark}, + update_by = #{updateBy}, + update_time = #{updateTime}, + + WHERE bill_no = #{billNo} + AND signer_role = '1' + AND is_delete = '0' + AND is_current = '1' + + delete from audit_signature where id = #{id} diff --git a/src/main/resources/mybatis/wisdom/RkInfoMapper.xml b/src/main/resources/mybatis/wisdom/RkInfoMapper.xml index 1fcf986..40ba118 100644 --- a/src/main/resources/mybatis/wisdom/RkInfoMapper.xml +++ b/src/main/resources/mybatis/wisdom/RkInfoMapper.xml @@ -84,7 +84,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" LEFT JOIN construction_team ct ON ri.team_code = ct.team_code - + INSERT INTO rk_info ( bill_no, rk_type, wl_type, cangku, lihuo_y, rk_time, @@ -340,6 +343,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" GROUP BY pcode + + update rk_info