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(); + } + /** * 查询销售合同信息 */