| | |
| | | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.approve.bean.vo.ApproveProcessVO; |
| | | import com.ruoyi.approve.pojo.ApproveProcess; |
| | | import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl; |
| | | import com.ruoyi.approve.bean.vo.ApproveProcessVO; |
| | | import com.ruoyi.basic.enums.ApplicationTypeEnum; |
| | | import com.ruoyi.basic.enums.RecordTypeEnum; |
| | | import com.ruoyi.basic.mapper.ProductMapper; |
| | | import com.ruoyi.basic.mapper.ProductModelMapper; |
| | | import com.ruoyi.basic.mapper.SupplierManageMapper; |
| | | import com.ruoyi.basic.pojo.Product; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.basic.pojo.SupplierManage; |
| | | import com.ruoyi.basic.utils.FileUtil; |
| | | import com.ruoyi.common.enums.FileNameType; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | |
| | | import com.ruoyi.framework.security.LoginUser; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.other.mapper.TempFileMapper; |
| | | import com.ruoyi.other.pojo.TempFile; |
| | | import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper; |
| | | import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage; |
| | | import com.ruoyi.project.system.domain.SysUser; |
| | |
| | | import com.ruoyi.sales.service.impl.CommonFileServiceImpl; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.io.FilenameUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Path; |
| | | import java.nio.file.Paths; |
| | | import java.nio.file.StandardCopyOption; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneId; |
| | |
| | | private final QualityInspectParamMapper qualityInspectParamMapper; |
| | | private final ApproveProcessServiceImpl approveProcessService; |
| | | private final ProcurementRecordMapper procurementRecordStorageMapper; |
| | | |
| | | @Value("${file.upload-dir}") |
| | | private String uploadDir; |
| | | private final FileUtil fileUtil; |
| | | |
| | | @Override |
| | | public List<PurchaseLedger> selectPurchaseLedgerList(PurchaseLedger purchaseLedger) { |
| | |
| | | } |
| | | purchaseLedgerMapper.updateById(purchaseLedger); |
| | | } |
| | | // 6.采购审核新增 |
| | | // 6.采购审核新增;审批管理未配置采购审批人时,审批服务会自动置为审批通过。 |
| | | addApproveByPurchase(loginUser, purchaseLedger); |
| | | |
| | | // 4. 处理子表数据 |
| | |
| | | // } |
| | | // } |
| | | // 5. 迁移临时文件到正式目录 |
| | | if (purchaseLedgerDto.getTempFileIds() != null && !purchaseLedgerDto.getTempFileIds().isEmpty()) { |
| | | migrateTempFilesToFormal(purchaseLedger.getId(), purchaseLedgerDto.getTempFileIds()); |
| | | } |
| | | fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.PURCHASE_LEDGER, purchaseLedger.getId(), purchaseLedgerDto.getStorageBlobDTOS()); |
| | | return 1; |
| | | } |
| | | |
| | |
| | | if (products == null || products.isEmpty()) { |
| | | throw new BaseException("产品信息不存在"); |
| | | } |
| | | Integer ledgerType = type == null ? 2 : type; |
| | | |
| | | // 提前收集所有需要查询的ID |
| | | Set<Long> productIds = products.stream() |
| | |
| | | // 执行更新操作 |
| | | if (!updateList.isEmpty()) { |
| | | for (SalesLedgerProduct product : updateList) { |
| | | product.setType(type); |
| | | product.setType(ledgerType); |
| | | salesLedgerProductMapper.updateById(product); |
| | | } |
| | | } |
| | | // 执行插入操作 |
| | | if (!insertList.isEmpty()) { |
| | | for (SalesLedgerProduct salesLedgerProduct : insertList) { |
| | | salesLedgerProduct.setType(type); |
| | | salesLedgerProduct.setType(ledgerType); |
| | | Date entryDate = purchaseLedger.getEntryDate(); |
| | | |
| | | LocalDateTime localDateTime = entryDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); |
| | |
| | | if (salesLedgerId != null) { |
| | | // 直接更新指定ID的记录的contractAmount字段为totalTaxInclusiveAmount |
| | | purchaseLedgerMapper.updateContractAmountById(salesLedgerId, totalTaxInclusiveAmount); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将临时文件迁移到正式目录 |
| | | * |
| | | * @param businessId 业务ID(销售台账ID) |
| | | * @param tempFileIds 临时文件ID列表 |
| | | * @throws IOException 文件操作异常 |
| | | */ |
| | | private void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds) throws IOException { |
| | | if (CollectionUtils.isEmpty(tempFileIds)) { |
| | | return; |
| | | } |
| | | |
| | | // 构建正式目录路径(按业务类型和日期分组) |
| | | String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE); |
| | | |
| | | Path formalDirPath = Paths.get(formalDir); |
| | | |
| | | // 确保正式目录存在(递归创建) |
| | | if (!Files.exists(formalDirPath)) { |
| | | Files.createDirectories(formalDirPath); |
| | | } |
| | | |
| | | for (String tempFileId : tempFileIds) { |
| | | // 查询临时文件记录 |
| | | TempFile tempFile = tempFileMapper.selectById(tempFileId); |
| | | if (tempFile == null) { |
| | | log.warn("临时文件不存在,跳过处理: {}", tempFileId); |
| | | continue; |
| | | } |
| | | |
| | | // 构建正式文件名(包含业务ID和时间戳,避免冲突) |
| | | String originalFilename = tempFile.getOriginalName(); |
| | | String fileExtension = FilenameUtils.getExtension(originalFilename); |
| | | String formalFilename = businessId + "_" + |
| | | System.currentTimeMillis() + "_" + |
| | | UUID.randomUUID().toString().substring(0, 8) + |
| | | (StringUtils.hasText(fileExtension) ? "." + fileExtension : ""); |
| | | |
| | | Path formalFilePath = formalDirPath.resolve(formalFilename); |
| | | |
| | | try { |
| | | // 执行文件迁移(使用原子操作确保安全性) |
| | | // Files.move( |
| | | // Paths.get(tempFile.getTempPath()), |
| | | // formalFilePath, |
| | | // StandardCopyOption.REPLACE_EXISTING, |
| | | // StandardCopyOption.ATOMIC_MOVE |
| | | // ); |
| | | // 原子移动失败,使用复制+删除 |
| | | Files.copy(Paths.get(tempFile.getTempPath()), formalFilePath, StandardCopyOption.REPLACE_EXISTING); |
| | | Files.deleteIfExists(Paths.get(tempFile.getTempPath())); |
| | | log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath); |
| | | |
| | | // 更新文件记录(关联到业务ID) |
| | | CommonFile fileRecord = new CommonFile(); |
| | | fileRecord.setCommonId(businessId); |
| | | fileRecord.setName(originalFilename); |
| | | fileRecord.setUrl(formalFilePath.toString()); |
| | | fileRecord.setCreateTime(LocalDateTime.now()); |
| | | fileRecord.setType(FileNameType.PURCHASE.getValue()); |
| | | commonFileMapper.insert(fileRecord); |
| | | |
| | | // 删除临时文件记录 |
| | | tempFileMapper.deleteById(tempFile); |
| | | |
| | | log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath); |
| | | } catch (IOException e) { |
| | | log.error("文件迁移失败: {}", tempFile.getTempPath(), e); |
| | | // 可选择回滚事务或记录失败文件 |
| | | throw new IOException("文件迁移异常", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | .eq(SalesLedgerProduct::getType, purchaseLedgerDto.getType()); |
| | | List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper); |
| | | |
| | | // 3.查询上传文件 |
| | | LambdaQueryWrapper<CommonFile> salesLedgerFileWrapper = new LambdaQueryWrapper<>(); |
| | | salesLedgerFileWrapper.eq(CommonFile::getCommonId, purchaseLedger.getId()) |
| | | .eq(CommonFile::getType,FileNameType.PURCHASE.getValue()); |
| | | List<CommonFile> salesLedgerFiles = commonFileMapper.selectList(salesLedgerFileWrapper); |
| | | |
| | | // 4. 转换 DTO |
| | | PurchaseLedgerDto resultDto = new PurchaseLedgerDto(); |
| | |
| | | if (!products.isEmpty()) { |
| | | resultDto.setHasChildren(true); |
| | | resultDto.setProductData(products); |
| | | resultDto.setSalesLedgerFiles(salesLedgerFiles); |
| | | resultDto.setStorageBlobVOS(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.FILE, RecordTypeEnum.PURCHASE_LEDGER, purchaseLedger.getId())); |
| | | } |
| | | return resultDto; |
| | | } |
| | |
| | | if(salesLedger1 != null){ |
| | | salesLedger.setSalesLedgerId(salesLedger1.getId()); |
| | | } |
| | | // 采购审核 |
| | | // 通过昵称获取用户ID |
| | | if (StringUtils.hasText(salesLedger.getApproveUserIds())) { |
| | | // 采购审核:历史导入模板传审批人姓名时,继续兼容转换为用户ID。 |
| | | String[] split = salesLedger.getApproveUserIds().split(","); |
| | | List<Long> ids = new ArrayList<>(); |
| | | for (int i = 0; i < split.length; i++) { |
| | |
| | | // 将集合转为字符串,隔开 |
| | | String collect = ids.stream().map(Object::toString).collect(Collectors.joining(",")); |
| | | salesLedger.setApproveUserIds(collect); |
| | | } |
| | | purchaseLedgerMapper.insert(salesLedger); |
| | | |
| | | for (PurchaseLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) { |
| | |
| | | } |
| | | |
| | | public void addApproveByPurchase(LoginUser loginUser,PurchaseLedger purchaseLedger) throws Exception { |
| | | if (loginUser == null) { |
| | | return; |
| | | } |
| | | ApproveProcessVO approveProcessVO = new ApproveProcessVO(); |
| | | approveProcessVO.setApproveType(5); |
| | | approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId()); |