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..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 @@ -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,19 @@ public class ConPurchaseController extends BaseController { public R updateAllStatic() { return toAjax(iConPurchaseService.updatePurchaseDaysOverdue()); } + + /** + * 采购合同导入 + * @param file + * @return + */ + @Log(title = "采购合同", businessType = BusinessType.IMPORT) + @PostMapping("/importData") + public R importData(MultipartFile file) { + try { + return R.ok(iConPurchaseService.importPurchase(file)); + } catch (Exception e) { + return R.fail(e.getMessage()); + } + } } 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/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/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/domain/vo/ConPurchaseImportVO.java b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/vo/ConPurchaseImportVO.java new file mode 100644 index 0000000..8589d4c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/contract/domain/vo/ConPurchaseImportVO.java @@ -0,0 +1,120 @@ +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; + +/** + * 采购合同导入VO + */ +@Data +public class ConPurchaseImportVO { + + @Alias("客户名称") + private String clientName; + + @Alias("优客项目编号") + private String projNumber; + + @Alias("合同编号") + private String contractNumber; + + @Alias("项目名称") + private String projName; + + @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; + + @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 secondName; + + @Alias("媒介部门") + private String mediaDeptName; + + @Alias("发票类型") + private String invoiceName; + + @Alias("税率") + private String taxPoints; + + @Alias("发票内容") + private String invoiceContent; + + @Alias("签订日期") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + 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..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 @@ -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) throws Exception; } 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/ConPurchaseServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/contract/service/impl/ConPurchaseServiceImpl.java index 22a2b48..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,7 +5,9 @@ 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; import cn.hutool.poi.excel.ExcelWriter; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -21,11 +23,16 @@ 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.*; 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 +45,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 +102,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 +124,181 @@ public class ConPurchaseServiceImpl implements IConPurchaseService { @Resource private IConFirstService iConFirstService; + @Resource + private Validator validator; + + /** + * 导入采购合同信息 + * @param file 导入文件 + * @return + * @throws Exception + */ + @Override + @Transactional(rollbackFor = Exception.class) + 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("导入数据不能为空"); + } + + // 按合同编号对导入数据进行分组 + Map> mapByContractNumber = list.stream() + .filter(vo -> StringUtils.isNotBlank(vo.getContractNumber())) + .collect(Collectors.groupingBy(ConPurchaseImportVO::getContractNumber)); + + // 遍历每个合同分组 + for (Map.Entry> entry : mapByContractNumber.entrySet()) { + String contractNumber = entry.getKey(); + List rows = entry.getValue(); + ConPurchaseImportVO firstRow = rows.get(0); // 使用第一行数据作为主信息 + + // 判断合同是否存在 + ConPurchase existingContract = baseMapper.selectOne(new LambdaQueryWrapper() + .eq(ConPurchase::getContractNumber, contractNumber)); + + 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()); + + // 状态转换 + String state = "生效".equals(firstRow.getState()) ? "1" : "0"; + purchaseBo.setState(state); + + // 关联客户ID + if (StringUtils.isNotBlank(firstRow.getClientName())) { + ConClient conClient = conClientMapper.selectOne(new LambdaQueryWrapper().eq(ConClient::getClientName, firstRow.getClientName())); + if (conClient != null) { + purchaseBo.setClientId(conClient.getId()); + } + } + + // 关联甲方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()); + } + } + + // 映射媒体子表信息 + 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); + + } 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; + } + try { + return Double.parseDouble(str); + } catch (NumberFormatException e) { + return null; + } + } + + /** * 查询采购合同信息 */ 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..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 @@ -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())) { + throw new ServiceException("合同编号不能为空"); + } + + 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(); + } + /** * 查询销售合同信息 */ 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" +