From 784b372f92e76b29d1fd0f4a9937fb70efdf8a35 Mon Sep 17 00:00:00 2001 From: zhanghuibin <18531122171@163.com> Date: Tue, 18 Nov 2025 22:53:02 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=90=88=E5=90=8C=E5=AF=BC?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ConPurchaseController.java | 12 ++ .../domain/vo/ConPurchaseImportVO.java | 114 +++++++++++++ .../contract/service/IConPurchaseService.java | 11 +- .../service/impl/ConPurchaseServiceImpl.java | 150 +++++++++++++++++- 4 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 ruoyi-system/src/main/java/com/ruoyi/contract/domain/vo/ConPurchaseImportVO.java diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/controller/ConPurchaseController.java b/ruoyi-system/src/main/java/com/ruoyi/contract/controller/ConPurchaseController.java index 22d5fc8..26be867 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/controller/ConPurchaseController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/controller/ConPurchaseController.java @@ -27,6 +27,7 @@ import com.ruoyi.contract.service.IConPurchaseService; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; @@ -209,4 +210,15 @@ public class ConPurchaseController extends BaseController { public R updateAllStatic() { return toAjax(iConPurchaseService.updatePurchaseDaysOverdue()); } + +// @Log(title = "采购合同", businessType = BusinessType.IMPORT) +// @SaCheckPermission("system:purchase:import") + @PostMapping("/importData") + public R importData(MultipartFile file) { + try { + return R.ok(iConPurchaseService.importPurchase(file)); + } catch (Exception e) { + return R.fail("导入失败"); + } + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/domain/vo/ConPurchaseImportVO.java b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/vo/ConPurchaseImportVO.java new file mode 100644 index 0000000..6ce2db4 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/vo/ConPurchaseImportVO.java @@ -0,0 +1,114 @@ +package com.ruoyi.contract.domain.vo; + +import cn.hutool.core.annotation.Alias; +import lombok.Data; +import java.util.Date; + +/** + * 采购合同导入VO + * + * @author ruoyi + * @date 2024-06-07 + */ +@Data +public class ConPurchaseImportVO { + + @Alias("客户名称") + private String clientName; + + @Alias("优客项目编号") + private String projNumber; + + @Alias("合同编号") + private String contractNumber; + + @Alias("项目名称") + private String projName; + + @Alias("城市") + private String cityName; + + @Alias("发布开始时间") + private Date startTime; + + @Alias("发布结束时间") + private Date endTime; + + @Alias("发布周期(天)") + private String publishDays; + + @Alias("媒体类型") + private String mediaType; + + @Alias("媒体位置") + private String mediaLocation; + + @Alias("采购数量") + private String purchaseQuantity; + + @Alias("频次") + private String frequency; + + @Alias("刊例价") + private String listPrice; + + @Alias("刊例价单位") + private String listPriceUnit; + + @Alias("折扣") + private String discount; + + @Alias("净价") + private String netPrice; + + @Alias("净价单位") + private String netPriceUnit; + + @Alias("制作费") + private String productionFee; + + @Alias("合同总金额") + private Double contractMoney; + + @Alias("甲方名称") + private String firstName; + + @Alias("供应商名称") + private String supplierName; + + @Alias("媒介部门") + private String mediaDeptName; + + @Alias("发票类型") + private String invoiceType; + + @Alias("税率") + private String taxRate; + + @Alias("发票内容") + private String invoiceContent; + + @Alias("签订日期") + private Date signTime; + + @Alias("合同附件") + private String contractAccess; + + @Alias("上刊") + private String upPrint; + + @Alias("换刊") + private String exchangePrint; + + @Alias("下刊") + private String nextPrint; + + @Alias("媒体链条") + private String mediaLink; + + @Alias("附件") + private String attachment; + + @Alias("状态") + private String state; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/service/IConPurchaseService.java b/ruoyi-system/src/main/java/com/ruoyi/contract/service/IConPurchaseService.java index 562189d..cb2137f 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/service/IConPurchaseService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/service/IConPurchaseService.java @@ -1,11 +1,11 @@ package com.ruoyi.contract.service; -import com.ruoyi.contract.domain.ConPurchase; import com.ruoyi.contract.domain.bo.conpurchase.ConPurchaseBoExtend; import com.ruoyi.contract.domain.vo.ConPurchaseVo; import com.ruoyi.contract.domain.bo.ConPurchaseBo; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.domain.PageQuery; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.util.Collection; @@ -98,4 +98,13 @@ public interface IConPurchaseService { * @return 列表内容 */ void dynamicexportUpgrade(String fieldName, String mediaFieldName, String ids, HttpServletResponse response); + + /** + * 导入采购合同 + * + * @param file 导入文件 + * @return 结果 + * @throws Exception + */ + int importPurchase(MultipartFile file); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConPurchaseServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConPurchaseServiceImpl.java index 3e343f0..962b09d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConPurchaseServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConPurchaseServiceImpl.java @@ -6,6 +6,7 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; +import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -26,6 +27,10 @@ import com.ruoyi.contract.domain.vo.conpurchasevo.ConPurchaseTotalVo; import com.ruoyi.contract.mapper.*; import com.ruoyi.contract.service.*; import lombok.RequiredArgsConstructor; +import com.ruoyi.contract.domain.vo.ConPurchaseImportVO; +import org.springframework.web.multipart.MultipartFile; +import java.io.InputStream; +import javax.validation.Validator; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -38,7 +43,6 @@ import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.net.URLEncoder; import java.util.*; -import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -96,6 +100,16 @@ public class ConPurchaseServiceImpl implements IConPurchaseService { private final IConMediaTypeService iConMediaTypeService; + private final ConFirstMapper conFirstMapper; + + private final ConInvoiceMapper conInvoiceMapper; + + private final ConMediaDeptMapper conMediaDeptMapper; + + private final ConPurchaseMediaMapper conPurchaseMediaMapper; + + private final ConMediaTypeMapper conMediaTypeMapper; + /** * 发票类型id */ @@ -108,6 +122,140 @@ public class ConPurchaseServiceImpl implements IConPurchaseService { @Resource private IConFirstService iConFirstService; + @Resource + private Validator validator; + + @Override + @Transactional(rollbackFor = Exception.class) + public int importPurchase(MultipartFile file) { + List list; + try (InputStream inputStream = file.getInputStream()) { + ExcelReader reader = ExcelUtil.getReader(inputStream); + list = reader.readAll(ConPurchaseImportVO.class); + } catch (IOException e) { + throw new ServiceException("导入采购合同失败"); + } + + if (CollectionUtil.isEmpty(list)) { + throw new ServiceException("导入数据不能为空"); + } + + for (int i = 0; i < list.size(); i++) { + ConPurchaseImportVO vo = list.get(i); + try { + // 校验必填项 + if (StringUtils.isBlank(vo.getContractNumber())) { + throw new ServiceException("合同编号不能为空"); + } + + ConPurchase conPurchase = baseMapper.selectOne(new LambdaQueryWrapper() + .eq(ConPurchase::getContractNumber, vo.getContractNumber())); + + if (conPurchase == null) { + // 不存在,新增合同 + conPurchase = new ConPurchase(); + // 手动进行字段映射 + conPurchase.setContractNumber(vo.getContractNumber()); + conPurchase.setProjNumber(vo.getProjNumber()); + conPurchase.setProjName(vo.getProjName()); + conPurchase.setStartTime(vo.getStartTime()); + conPurchase.setEndTime(vo.getEndTime()); + conPurchase.setContractMoney(vo.getContractMoney()); + conPurchase.setInvoiceContent(vo.getInvoiceContent()); + conPurchase.setSignTime(vo.getSignTime()); + conPurchase.setUpPrint(vo.getUpPrint()); + conPurchase.setExchangePrint(vo.getExchangePrint()); + conPurchase.setNextPrint(vo.getNextPrint()); + conPurchase.setMediaLink(vo.getMediaLink()); + String state = "生效".equals(vo.getState()) ? "1" : "0"; + conPurchase.setState(state); + conPurchase.setFirstName(vo.getFirstName()); + conPurchase.setMediaDeptName(vo.getMediaDeptName()); + // 供应商名称(乙方名称) + conPurchase.setSecondName(vo.getSupplierName()); + //税率(税点) + conPurchase.setTaxPoints(vo.getTaxRate()); + + //甲方 + if (StringUtils.isNotBlank(vo.getFirstName())) { + ConFirst conFirst = conFirstMapper.selectOne(new LambdaQueryWrapper().eq(ConFirst::getFirstName, vo.getFirstName())); + if (conFirst != null) { + conPurchase.setFirstId(conFirst.getId()); + } + } + //媒介部门 + if (StringUtils.isNotBlank(vo.getMediaDeptName())) { + ConMediaDept conMediaDept = conMediaDeptMapper.selectOne(new LambdaQueryWrapper().eq(ConMediaDept::getMediaDeptName, vo.getMediaDeptName())); + if (conMediaDept != null) { + conPurchase.setMediaDeptId(conMediaDept.getId()); + } + } + //发票类型 + if (StringUtils.isNotBlank(vo.getInvoiceType())) { + ConInvoice conInvoice = conInvoiceMapper.selectOne(new LambdaQueryWrapper().eq(ConInvoice::getInvoiceName, vo.getInvoiceType())); + if (conInvoice != null) { + conPurchase.setInvoiceId(conInvoice.getId()); + } + } + + validEntityBeforeSave(conPurchase); + baseMapper.insert(conPurchase); + } + + // 新增媒体数据 + ConPurchaseMedia conPurchaseMedia = new ConPurchaseMedia(); + conPurchaseMedia.setPurchaseId(conPurchase.getId()); + + // 媒体类型 + if (StringUtils.isNotBlank(vo.getMediaType())) { + ConMediaType conMediaType = conMediaTypeMapper.selectOne(new LambdaQueryWrapper().eq(ConMediaType::getMediaType, vo.getMediaType())); + if (conMediaType != null) { + conPurchaseMedia.setMediaId(conMediaType.getId()); + } + } + //城市 + if (StringUtils.isNotBlank(vo.getCityName())) { + ConCity conCity = conCityMapper.selectList(new LambdaQueryWrapper().likeRight(ConCity::getCityName, vo.getCityName())).stream().findFirst().orElse(null); + if (conCity != null) { + conPurchaseMedia.setCityId(conCity.getId()); + String cityIds = iConCityService.selectTreeIds(conCity.getId()); + conPurchaseMedia.setCityIds(cityIds); + } + } + conPurchaseMedia.setMediaPosition(vo.getMediaLocation()); + conPurchaseMedia.setAccountNumber(safeParseDouble(vo.getPurchaseQuantity())); + conPurchaseMedia.setReleaseFrequency(vo.getFrequency()); + conPurchaseMedia.setUpTime(vo.getStartTime()); + conPurchaseMedia.setDownTime(vo.getEndTime()); + conPurchaseMedia.setPeriod(safeParseDouble(vo.getPublishDays())); + conPurchaseMedia.setPrintPrice(safeParseDouble(vo.getListPrice())); + conPurchaseMedia.setPrintPriceUnit(vo.getListPriceUnit()); + conPurchaseMedia.setDiscount(vo.getDiscount()); + conPurchaseMedia.setMediaFee(safeParseDouble(vo.getNetPrice())); + conPurchaseMedia.setProductFee(safeParseDouble(vo.getProductionFee())); + + conPurchaseMediaMapper.insert(conPurchaseMedia); + + + } catch (Exception e) { + log.error("导入采购合同失败", e); + } + } + return list.size(); + } + + private Double safeParseDouble(String str) { + if (StringUtils.isBlank(str) || "-".equals(str)) { + return null; + } + try { + return Double.parseDouble(str); + } catch (NumberFormatException e) { + return null; + } + } + + /** * 查询采购合同信息 */