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 1/5] =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=90=88=E5=90=8C?= =?UTF-8?q?=E5=AF=BC=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; + } + } + + /** * 查询采购合同信息 */ From 4ecd736cbd4e5774dd1fc4542a2d6295df70ac23 Mon Sep 17 00:00:00 2001 From: zhanghuibin <18531122171@163.com> Date: Wed, 19 Nov 2025 14:52:57 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E9=94=80=E5=94=AE=E5=90=88=E5=90=8C?= =?UTF-8?q?=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ConPurchaseController.java | 8 +- .../controller/ConSaleController.java | 15 ++ .../contract/domain/bo/ConSaleMediaBo.java | 14 ++ .../contract/domain/dto/ConSaleImportDto.java | 119 +++++++++++++++ .../contract/service/IConSaleService.java | 17 ++- .../service/impl/ConSaleMediaServiceImpl.java | 5 + .../service/impl/ConSaleServiceImpl.java | 144 ++++++++++++++++-- 7 files changed, 299 insertions(+), 23 deletions(-) create mode 100644 ruoyi-system/src/main/java/com/ruoyi/contract/domain/dto/ConSaleImportDto.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 26be867..93c5de1 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 @@ -211,8 +211,12 @@ public class ConPurchaseController extends BaseController { return toAjax(iConPurchaseService.updatePurchaseDaysOverdue()); } -// @Log(title = "采购合同", businessType = BusinessType.IMPORT) -// @SaCheckPermission("system:purchase:import") + /** + * 采购合同导入 + * @param file + * @return + */ + @Log(title = "采购合同", businessType = BusinessType.IMPORT) @PostMapping("/importData") public R importData(MultipartFile file) { try { diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/controller/ConSaleController.java b/ruoyi-system/src/main/java/com/ruoyi/contract/controller/ConSaleController.java index 4be3ef6..4c37282 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/controller/ConSaleController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/controller/ConSaleController.java @@ -804,4 +804,19 @@ public class ConSaleController extends BaseController { } + /** + * 销售合同导入 + * @param file + * @return + */ + @Log(title = "销售合同导入", businessType = BusinessType.IMPORT) + @PostMapping("/importData") + public R importData(MultipartFile file) { + try { + return R.ok(iConSaleService.importData(file)); + } catch (Exception e) { + return R.fail("导入失败"); + } + } + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/domain/bo/ConSaleMediaBo.java b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/bo/ConSaleMediaBo.java index 3be6229..88bf6b1 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/domain/bo/ConSaleMediaBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/bo/ConSaleMediaBo.java @@ -189,4 +189,18 @@ public class ConSaleMediaBo extends BaseEntityAdd { @CustomBaenAnnotation(value = "其他返点金额") @Digits(integer = 15,fraction = 4,message = "其他返点金额最多允许15位整数,4位小数") private Double otherReverMoney; + + /** + * 其他返点2 + */ + @CustomBaenAnnotation(value = "其他返点2") + @Digits(integer = 15,fraction = 4,message = "其他返点2最多允许15位整数,4位小数") + private String otherReverPoit2; + + /** + * 其他返点金额2 + */ + @CustomBaenAnnotation(value = "其他返点金额2") + @Digits(integer = 15,fraction = 4,message = "其他返点金额2最多允许15位整数,4位小数") + private Double otherReverMoney2; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/domain/dto/ConSaleImportDto.java b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/dto/ConSaleImportDto.java new file mode 100644 index 0000000..6932094 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/dto/ConSaleImportDto.java @@ -0,0 +1,119 @@ +package com.ruoyi.contract.domain.dto; + +import cn.hutool.core.annotation.Alias; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 销售合同导入DTO + * 用于接收Hutool Excel读取的数据 + */ +@Data +public class ConSaleImportDto implements Serializable { + + private static final long serialVersionUID = 1L; + + @Alias("客户名称") + private String clientName; + + @Alias("优客项目编号") + private String contractNo; + + @Alias("订单编号") + private String projectNo; + + @Alias("项目名称") + private String projectName; + + @Alias("城市") + private String city; + + @Alias("发布开始时间") + private String publishStartDate; + + @Alias("发布结束时间") + private String publishEndDate; + + @Alias("发布周期(天)") + private Double publishCycle; + + @Alias("媒体类型") + private String mediaType; + + @Alias("媒体位置") + private String mediaPosition; + + @Alias("数量") + private Double quantity; + + @Alias("频次") + private String frequency; + + @Alias("刊例价") + private Double listPrice; + + @Alias("刊例价单位") + private String listPriceUnit; + + @Alias("折扣") + private String discount; + + @Alias("订单发布费") + private Double mediaFee; + + @Alias("订单制作费(修改字段)") + private Double productionFee; + + @Alias("订单总金额") + private Double totalAmount; + + @Alias("比稿") + private String isBid; + + @Alias("比稿返点") + private String bidRebate; + + @Alias("比稿返点金额") + private Double bidRebateAmount = 0.0; + + @Alias("其他返点1") + private String otherReverPoit = "0"; + + @Alias("其他返点金额1") + private Double otherReverMoney = 0.0; + + @Alias("其他返点2") + private String otherReverPoit2 = "0"; + + @Alias("其他返点金额2") + private Double otherReverMoney2 = 0.0; + + @Alias("开票时间") + private String invoiceDate; + + @Alias("甲方名称") + private String partyA; + + @Alias("乙方名称") + private String partyB; + + @Alias("签订日期") + private String signDate; + + @Alias("合同附件") + private String contractAttachment; + + @Alias("其他附件") + private String otherAttachment; + + @Alias("补充说明") + private String notes; + + @Alias("状态") + private String status; + + @Alias("项目执行人") + private String projectExecutor; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/service/IConSaleService.java b/ruoyi-system/src/main/java/com/ruoyi/contract/service/IConSaleService.java index 4d4dc42..7a7195d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/service/IConSaleService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/service/IConSaleService.java @@ -1,24 +1,18 @@ package com.ruoyi.contract.service; -import com.ruoyi.contract.domain.ConOtherPayment; import com.ruoyi.contract.domain.ConSale; import com.ruoyi.contract.domain.bo.ConStaticBo; import com.ruoyi.contract.domain.bo.consale.ConSaleBoExtend; -import com.ruoyi.contract.domain.bo.consale.ConSaleExcelSearch; -import com.ruoyi.contract.domain.bo.consale.ConSaleSearch; import com.ruoyi.contract.domain.bo.consale.ConSaleTotalVo; import com.ruoyi.contract.domain.vo.ConSaleVo; import com.ruoyi.contract.domain.bo.ConSaleBo; 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.io.Console; -import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.util.Collection; import java.util.List; -import java.util.Map; /** * 销售合同信息Service接口 @@ -105,4 +99,13 @@ public interface IConSaleService { * 更新同步统计表字段 */ ConStaticBo updateStaticDate(ConSale add); + + /** + * 导入销售合同 + * + * @param file 导入的Excel文件 + * @return 导入结果信息 + * @throws Exception 导入过程中可能抛出的异常 + */ + int importData(MultipartFile file) throws Exception; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleMediaServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleMediaServiceImpl.java index 385c21e..b0b1968 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleMediaServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleMediaServiceImpl.java @@ -179,6 +179,11 @@ public class ConSaleMediaServiceImpl implements IConSaleMediaService { bean.setOtherReverPoit(bean.getOtherReverPoit() + "%"); } } + if (ObjectUtil.isNotNull(bean.getOtherReverPoit2())){ + if (!bean.getOtherReverPoit2().contains("%")){ + bean.setOtherReverPoit(bean.getOtherReverPoit2() + "%"); + } + } System.out.println(bean.getCityId()); return bean; }).collect(Collectors.toList()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleServiceImpl.java index d3e61b8..2d8ed67 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleServiceImpl.java @@ -7,12 +7,9 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; 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.Wrapper; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; -import com.ruoyi.common.annotation.RepeatSubmit; -import com.ruoyi.common.annotation.Translation; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateSpeciUtil; import com.ruoyi.common.utils.FieldCompare; @@ -27,30 +24,23 @@ import com.ruoyi.common.utils.sql.HeadExcelUtils; import com.ruoyi.contract.domain.*; import com.ruoyi.contract.domain.bo.*; import com.ruoyi.contract.domain.bo.consale.ConSaleBoExtend; -import com.ruoyi.contract.domain.bo.consale.ConSaleExcelSearch; import com.ruoyi.contract.domain.bo.consale.ConSaleSearch; import com.ruoyi.contract.domain.bo.consale.ConSaleTotalVo; +import com.ruoyi.contract.domain.dto.ConSaleImportDto; import com.ruoyi.contract.domain.vo.*; -import com.ruoyi.contract.domain.vo.conpurchasevo.ConPurchaseTotalVo; -import com.ruoyi.contract.mapper.ConCityMapper; -import com.ruoyi.contract.mapper.ConClientMapper; +import com.ruoyi.contract.mapper.*; import com.ruoyi.contract.service.*; -import com.sun.corba.se.spi.orbutil.threadpool.WorkQueue; import lombok.RequiredArgsConstructor; -import org.ehcache.impl.internal.loaderwriter.writebehind.BatchingLocalHeapWriteBehindQueue; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.ruoyi.contract.mapper.ConSaleMapper; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; -import java.io.Console; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; -import java.math.MathContext; import java.net.URLEncoder; import java.util.*; import java.util.stream.Collectors; @@ -136,6 +126,132 @@ public class ConSaleServiceImpl implements IConSaleService { @Resource private IConMediaTypeService iConMediaTypeService; + private final ConFirstMapper conFirstMapper; + + private final ConMediaTypeMapper conMediaTypeMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public int importData(MultipartFile file) throws Exception { + ExcelReader reader = ExcelUtil.getReader(file.getInputStream()); + // 读取所有行数据到DTO列表 + List dtoList = reader.readAll(ConSaleImportDto.class); + reader.close(); + + if (CollUtil.isEmpty(dtoList)) { + throw new ServiceException("导入数据为空!"); + } + + for (ConSaleImportDto row : dtoList) { + // 校验项目编号(订单编号)是否为空 + if (StringUtils.isBlank(row.getProjectNo())) { + continue; + } + + ConSaleBo saleBo = new ConSaleBo(); + saleBo.setContractNumber(row.getContractNo()); // 合同编号 (来自“优客项目编号”) + saleBo.setProjNumber(row.getProjectNo()); // 项目编号 (来自“订单编号”) + saleBo.setProjName(row.getProjectName()); + saleBo.setProjExecutor(row.getProjectExecutor()); + saleBo.setSecondName(row.getPartyB()); + saleBo.setSupple(row.getNotes()); + String state = "生效".equals(row.getStatus()) ? "1" : "0"; + saleBo.setContractMoney(row.getTotalAmount()); + saleBo.setState(state); + + // 根据客户名称查询客户ID + if (StringUtils.isNotBlank(row.getClientName())) { + ConClient client = conClientMapper.selectOne(new LambdaQueryWrapper().eq(ConClient::getClientName, row.getClientName())); + if (client != null) { + saleBo.setClientId(client.getId()); + saleBo.setClientName(client.getClientName()); + } + } + + // 根据甲方名称查询甲方ID + if (StringUtils.isNotBlank(row.getPartyA())) { + ConFirst first = conFirstMapper.selectOne(new LambdaQueryWrapper().eq(ConFirst::getFirstName, row.getPartyA())); + if (first != null) { + saleBo.setFirstId(first.getId()); + saleBo.setFirstName(first.getFirstName()); + } + } + + // 解析日期 + try { + if (StringUtils.isNotBlank(row.getSignDate())) { + saleBo.setSignTime(DateUtil.parse(row.getSignDate(), "yyyy-MM-dd")); + } + if (StringUtils.isNotBlank(row.getInvoiceDate())) { + saleBo.setBillingTime(DateUtil.parse(row.getInvoiceDate(), "yyyy-MM-dd")); + } + } catch (Exception e) { + throw new ServiceException("订单 " + row.getProjectNo() + " 的签约或开票日期格式不正确,请使用 yyyy-MM-dd 格式"); + } + + ConSaleMediaBo mediaBo = new ConSaleMediaBo(); + + // 根据城市名称查询城市ID + if (StringUtils.isNotBlank(row.getCity())) { + ConCity conCity = conCityMapper.selectList(new LambdaQueryWrapper().likeRight(ConCity::getCityName, row.getCity())).stream().findFirst().orElse(null); + if (conCity != null) { + mediaBo.setCityId(conCity.getId()); + mediaBo.setCityName(conCity.getCityName()); + String cityIds = iConCityService.selectTreeIds(conCity.getId()); + mediaBo.setCityIds(cityIds); + } + } + + // 根据媒体类型查询ID + if (StringUtils.isNotBlank(row.getMediaType())) { + ConMediaType mediaType = conMediaTypeMapper.selectOne(new LambdaQueryWrapper().eq(ConMediaType::getMediaType, row.getMediaType())); + if (mediaType != null) { + mediaBo.setMediaId(mediaType.getId()); + mediaBo.setMediaName(mediaType.getMediaType()); + } + } + + mediaBo.setMediaPosition(row.getMediaPosition()); + mediaBo.setAccountNumber(row.getQuantity()); + mediaBo.setReleaseFrequency(row.getFrequency()); + mediaBo.setPrintPrice(row.getListPrice()); + mediaBo.setPrintPriceUnit(row.getListPriceUnit()); + mediaBo.setDiscount(row.getDiscount()); + mediaBo.setMediaFee(row.getMediaFee()); + mediaBo.setProductFee(row.getProductionFee()); + mediaBo.setCompet("是".equals(row.getIsBid()) ? "1" : "2"); + mediaBo.setRemark(row.getNotes()); + mediaBo.setPeriod(row.getPublishCycle()); + mediaBo.setCompetReverPoit(StrUtil.isNotBlank(row.getBidRebate()) ? row.getBidRebate() : "0"); + mediaBo.setCompetReverMoney(ObjectUtil.isNotNull(row.getBidRebateAmount()) ? row.getBidRebateAmount() : 0.0); + mediaBo.setOtherReverPoit(StrUtil.isNotBlank(row.getOtherReverPoit()) ? row.getOtherReverPoit() : "0"); + mediaBo.setOtherReverMoney(ObjectUtil.isNotNull(row.getOtherReverMoney()) ? row.getOtherReverMoney() : 0.0); + mediaBo.setOtherReverPoit2(StrUtil.isNotBlank(row.getOtherReverPoit2()) ? row.getOtherReverPoit2() : "0"); + mediaBo.setOtherReverMoney2(ObjectUtil.isNotNull(row.getOtherReverMoney2()) ? row.getOtherReverMoney2() : 0.0); + + // 解析日期 + try { + if (StringUtils.isNotBlank(row.getPublishStartDate())) { + mediaBo.setUpTime(DateUtil.parse(row.getPublishStartDate(), "yyyy-MM-dd")); + } + if (StringUtils.isNotBlank(row.getPublishEndDate())) { + mediaBo.setDownTime(DateUtil.parse(row.getPublishEndDate(), "yyyy-MM-dd")); + } + } catch (Exception e) { + throw new ServiceException("订单 " + row.getProjectNo() + " 的发布起止日期格式不正确,请使用 yyyy-MM-dd 格式"); + } + + List mediaList = new ArrayList<>(); + mediaList.add(mediaBo); + saleBo.setConSaleMediaBoList(mediaList); + + // 调用现有服务将封装好的 saleBo 存入数据库 + this.insertByBo(saleBo); + } + + return dtoList.size(); + } + /** * 查询销售合同信息 */ From 6910611c61da71ea37d4dfae82376e086412219c Mon Sep 17 00:00:00 2001 From: zhanghuibin <18531122171@163.com> Date: Wed, 19 Nov 2025 17:06:50 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=87=87=E8=B4=AD?= =?UTF-8?q?=E5=90=88=E5=90=8C=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ConPurchaseController.java | 2 +- .../contract/domain/ConPurchaseMedia.java | 5 + .../domain/bo/ConPurchaseMediaBo.java | 6 + .../domain/vo/ConPurchaseImportVO.java | 15 +- .../contract/service/IConPurchaseService.java | 2 +- .../service/impl/ConPurchaseServiceImpl.java | 233 +++++++++++------- .../contract/ConPurchaseMediaMapper.xml | 1 + 7 files changed, 164 insertions(+), 100 deletions(-) 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 93c5de1..ce35ceb 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 @@ -222,7 +222,7 @@ public class ConPurchaseController extends BaseController { try { return R.ok(iConPurchaseService.importPurchase(file)); } catch (Exception e) { - return R.fail("导入失败"); + return R.fail(e.getMessage()); } } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/domain/ConPurchaseMedia.java b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/ConPurchaseMedia.java index c657eee..d642cba 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/domain/ConPurchaseMedia.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/ConPurchaseMedia.java @@ -115,6 +115,11 @@ public class ConPurchaseMedia extends BaseEntity { */ @FieldNameApi(name ="媒体费") private Double mediaFee; + /** + * 媒体费单位 + */ + @FieldNameApi(name ="媒体费单位") + private String mediaFeeUnit; /** * 制作费 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/domain/bo/ConPurchaseMediaBo.java b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/bo/ConPurchaseMediaBo.java index ff97b69..577879e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/domain/bo/ConPurchaseMediaBo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/bo/ConPurchaseMediaBo.java @@ -151,6 +151,12 @@ public class ConPurchaseMediaBo extends BaseEntity { @CustomBaenAnnotation(value = "媒体费") private Double mediaFee; + /** + * 媒体费单位 + */ + @CustomBaenAnnotation(value = "媒体费单位") + private String mediaFeeUnit; + /** * 制作费 */ 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 index 6ce2db4..9a7cfd7 100644 --- 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 @@ -1,7 +1,10 @@ package com.ruoyi.contract.domain.vo; import cn.hutool.core.annotation.Alias; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + import java.util.Date; /** @@ -28,9 +31,13 @@ public class ConPurchaseImportVO { @Alias("城市") private String cityName; + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") @Alias("发布开始时间") private Date startTime; + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") @Alias("发布结束时间") private Date endTime; @@ -74,21 +81,23 @@ public class ConPurchaseImportVO { private String firstName; @Alias("供应商名称") - private String supplierName; + private String secondName; @Alias("媒介部门") private String mediaDeptName; @Alias("发票类型") - private String invoiceType; + private String invoiceName; @Alias("税率") - private String taxRate; + private String taxPoints; @Alias("发票内容") private String invoiceContent; @Alias("签订日期") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") private Date signTime; @Alias("合同附件") 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 cb2137f..c9c0b96 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 @@ -106,5 +106,5 @@ public interface IConPurchaseService { * @return 结果 * @throws Exception */ - int importPurchase(MultipartFile file); + int importPurchase(MultipartFile file) throws Exception; } 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 81bd3f0..e018624 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 @@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; @@ -22,6 +23,7 @@ import com.ruoyi.common.utils.sql.HeadExcelUtils; import com.ruoyi.contract.domain.*; import com.ruoyi.contract.domain.bo.*; import com.ruoyi.contract.domain.bo.conpurchase.ConPurchaseBoExtend; +import com.ruoyi.contract.domain.dto.ConSaleImportDto; import com.ruoyi.contract.domain.vo.*; import com.ruoyi.contract.domain.vo.conpurchasevo.ConPurchaseTotalVo; import com.ruoyi.contract.mapper.*; @@ -125,125 +127,166 @@ public class ConPurchaseServiceImpl implements IConPurchaseService { @Resource private Validator validator; + /** + * 导入采购合同信息 + * @param file 导入文件 + * @return + * @throws Exception + */ @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("导入采购合同失败"); - } + public int importPurchase(MultipartFile file) throws Exception { + ExcelReader reader = ExcelUtil.getReader(file.getInputStream()); + List list = reader.readAll(ConPurchaseImportVO.class); + reader.close(); 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("合同编号不能为空"); - } + // 按合同编号对导入数据进行分组 + Map> mapByContractNumber = list.stream() + .filter(vo -> StringUtils.isNotBlank(vo.getContractNumber())) + .collect(Collectors.groupingBy(ConPurchaseImportVO::getContractNumber)); - ConPurchase conPurchase = baseMapper.selectOne(new LambdaQueryWrapper() - .eq(ConPurchase::getContractNumber, vo.getContractNumber())); + // 遍历每个合同分组 + for (Map.Entry> entry : mapByContractNumber.entrySet()) { + String contractNumber = entry.getKey(); + List rows = entry.getValue(); + ConPurchaseImportVO firstRow = rows.get(0); // 使用第一行数据作为主信息 - 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()); + // 判断合同是否存在 + ConPurchase existingContract = baseMapper.selectOne(new LambdaQueryWrapper() + .eq(ConPurchase::getContractNumber, contractNumber)); - //甲方 - 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()); - } - } + if (existingContract == null) { + // 合同不存在 -> 调用 insertByBo 新增 + ConPurchaseBo purchaseBo = new ConPurchaseBo(); + // 手动映射主表字段 + purchaseBo.setContractNumber(firstRow.getContractNumber()); + purchaseBo.setProjNumber(firstRow.getProjNumber()); + purchaseBo.setProjName(firstRow.getProjName()); + purchaseBo.setStartTime(firstRow.getStartTime()); + purchaseBo.setEndTime(firstRow.getEndTime()); + purchaseBo.setContractMoney(firstRow.getContractMoney()); + purchaseBo.setInvoiceContent(firstRow.getInvoiceContent()); + purchaseBo.setSignTime(firstRow.getSignTime()); + purchaseBo.setUpPrint(firstRow.getUpPrint()); + purchaseBo.setExchangePrint(firstRow.getExchangePrint()); + purchaseBo.setNextPrint(firstRow.getNextPrint()); + purchaseBo.setMediaLink(firstRow.getMediaLink()); + purchaseBo.setFirstName(firstRow.getFirstName()); + purchaseBo.setMediaDeptName(firstRow.getMediaDeptName()); + purchaseBo.setSecondName(firstRow.getSecondName()); // 供应商名称(乙方名称) + purchaseBo.setTaxPoints(firstRow.getTaxPoints()); // 税率(税点) + purchaseBo.setMediaLink(firstRow.getMediaLink()); - validEntityBeforeSave(conPurchase); - baseMapper.insert(conPurchase); - } + // 状态转换 + String state = "生效".equals(firstRow.getState()) ? "1" : "0"; + purchaseBo.setState(state); - // 新增媒体数据 - 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()); + // 关联客户ID + if (StringUtils.isNotBlank(firstRow.getClientName())) { + ConClient conClient = conClientMapper.selectOne(new LambdaQueryWrapper().eq(ConClient::getClientName, firstRow.getClientName())); + if (conClient != null) { + purchaseBo.setClientId(conClient.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); + + // 关联甲方ID + if (StringUtils.isNotBlank(firstRow.getFirstName())) { + ConFirst conFirst = conFirstMapper.selectOne(new LambdaQueryWrapper().eq(ConFirst::getFirstName, firstRow.getFirstName())); + if (conFirst != null) { + purchaseBo.setFirstId(conFirst.getId()); + } + } + // 关联媒介部门ID + if (StringUtils.isNotBlank(firstRow.getMediaDeptName())) { + ConMediaDept conMediaDept = conMediaDeptMapper.selectOne(new LambdaQueryWrapper().eq(ConMediaDept::getMediaDeptName, firstRow.getMediaDeptName())); + if (conMediaDept != null) { + purchaseBo.setMediaDeptId(conMediaDept.getId()); + } + } + // 关联发票类型ID + if (StringUtils.isNotBlank(firstRow.getInvoiceName())) { + ConInvoice conInvoice = conInvoiceMapper.selectOne(new LambdaQueryWrapper().eq(ConInvoice::getInvoiceName, firstRow.getInvoiceName())); + if (conInvoice != null) { + purchaseBo.setInvoiceId(conInvoice.getId()); } } - 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); + // 映射媒体子表信息 + List mediaBoList = rows.stream().map(row -> { + ConPurchaseMediaBo mediaBo = new ConPurchaseMediaBo(); + this.mapRowToMediaBo(row, mediaBo); + return mediaBo; + }).collect(Collectors.toList()); + purchaseBo.setPurchaseMediaBoList(mediaBoList); + this.insertByBo(purchaseBo); - } catch (Exception e) { - log.error("导入采购合同失败", e); + } else { + // 合同已存在 -> 调用 updateByBo 追加媒体信息 + ConPurchaseVo existingVo = this.queryById(existingContract.getId()); + ConPurchaseBo purchaseBo = BeanUtil.toBean(existingVo, ConPurchaseBo.class); + + // 获取已有的媒体信息 + List existingMedia = purchaseBo.getPurchaseMediaBoList(); + if (existingMedia == null) { + existingMedia = new ArrayList<>(); + } + + // 创建并添加本次导入的新媒体信息 + List newMediaList = rows.stream().map(row -> { + ConPurchaseMediaBo mediaBo = new ConPurchaseMediaBo(); + this.mapRowToMediaBo(row, mediaBo); + return mediaBo; + }).collect(Collectors.toList()); + existingMedia.addAll(newMediaList); + purchaseBo.setPurchaseMediaBoList(existingMedia); + + this.updateByBo(purchaseBo); } } return list.size(); } + /** + * 辅助方法:将导入行数据映射到媒体BO + */ + private void mapRowToMediaBo(ConPurchaseImportVO row, ConPurchaseMediaBo mediaBo) { + // 媒体类型 + if (StringUtils.isNotBlank(row.getMediaType())) { + ConMediaType conMediaType = conMediaTypeMapper.selectOne(new LambdaQueryWrapper().eq(ConMediaType::getMediaType, row.getMediaType())); + if (conMediaType != null) { + mediaBo.setMediaId(conMediaType.getId()); + mediaBo.setMediaName(conMediaType.getMediaType()); + } + } + // 城市 + if (StringUtils.isNotBlank(row.getCityName())) { + ConCity conCity = conCityMapper.selectList(new LambdaQueryWrapper().likeRight(ConCity::getCityName, row.getCityName())).stream().findFirst().orElse(null); + if (conCity != null) { + mediaBo.setCityId(conCity.getId()); + mediaBo.setCityName(conCity.getCityName()); + String cityIds = iConCityService.selectTreeIds(conCity.getId()); + mediaBo.setCityIds(cityIds); + } + } + mediaBo.setMediaPosition(row.getMediaLocation()); + mediaBo.setAccountNumber(safeParseDouble(row.getPurchaseQuantity())); + mediaBo.setReleaseFrequency(row.getFrequency()); + mediaBo.setUpTime(row.getStartTime()); + mediaBo.setDownTime(row.getEndTime()); + mediaBo.setPeriod(safeParseDouble(row.getPublishDays())); + mediaBo.setPrintPrice(safeParseDouble(row.getListPrice())); + mediaBo.setPrintPriceUnit(row.getListPriceUnit()); + mediaBo.setDiscount(StrUtil.isNotBlank(row.getDiscount()) ? row.getDiscount() : "0"); + mediaBo.setMediaFee(safeParseDouble(row.getNetPrice())); + mediaBo.setMediaFeeUnit(row.getNetPriceUnit()); + mediaBo.setProductFee(safeParseDouble(row.getProductionFee())); + } + private Double safeParseDouble(String str) { if (StringUtils.isBlank(str) || "-".equals(str)) { return null; diff --git a/ruoyi-system/src/main/resources/mapper/contract/ConPurchaseMediaMapper.xml b/ruoyi-system/src/main/resources/mapper/contract/ConPurchaseMediaMapper.xml index d809904..6075291 100644 --- a/ruoyi-system/src/main/resources/mapper/contract/ConPurchaseMediaMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/contract/ConPurchaseMediaMapper.xml @@ -18,6 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + From 89aa22cd787c7dc91fb98b063e1d93bcf7a518c7 Mon Sep 17 00:00:00 2001 From: zhanghuibin <18531122171@163.com> Date: Wed, 19 Nov 2025 17:07:13 +0800 Subject: [PATCH 4/5] update --- .../com/ruoyi/contract/service/impl/ConSaleServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleServiceImpl.java index 2d8ed67..e48f985 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConSaleServiceImpl.java @@ -145,7 +145,7 @@ public class ConSaleServiceImpl implements IConSaleService { for (ConSaleImportDto row : dtoList) { // 校验项目编号(订单编号)是否为空 if (StringUtils.isBlank(row.getProjectNo())) { - continue; + throw new ServiceException("合同编号不能为空"); } ConSaleBo saleBo = new ConSaleBo(); From 1cffd78f1445a8220c096bbe85c6255eb66cae19 Mon Sep 17 00:00:00 2001 From: zhanghuibin <18531122171@163.com> Date: Wed, 19 Nov 2025 17:20:02 +0800 Subject: [PATCH 5/5] delete author --- .../java/com/ruoyi/contract/domain/vo/ConPurchaseImportVO.java | 3 --- 1 file changed, 3 deletions(-) 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 index 9a7cfd7..8589d4c 100644 --- 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 @@ -9,9 +9,6 @@ import java.util.Date; /** * 采购合同导入VO - * - * @author ruoyi - * @date 2024-06-07 */ @Data public class ConPurchaseImportVO {