src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesNearExpiryController.java
@@ -2,16 +2,25 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.aftersalesservice.dto.AfterSalesNearExpiryExportDto; import com.ruoyi.aftersalesservice.dto.AfterSalesNearExpiryImportDto; import com.ruoyi.aftersalesservice.pojo.AfterSalesNearExpiry; import com.ruoyi.aftersalesservice.service.AfterSalesNearExpiryService; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.controller.BaseController; import com.ruoyi.framework.web.domain.AjaxResult; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.List; /** * <br> @@ -74,4 +83,46 @@ return AjaxResult.success(listPage); } /** * å¯¼å ¥ä¸´æå®å */ @PostMapping("/import") @Operation(summary = "临æå®å管ç-å¯¼å ¥") @Log(title = "临æå®å管ç-å¯¼å ¥", businessType = BusinessType.IMPORT) public AjaxResult importData(MultipartFile file) { return afterSalesNearExpiryService.importData(file); } /** * ä¸è½½å¯¼å ¥æ¨¡æ¿ */ @PostMapping("/importTemplate") @Operation(summary = "临æå®å管ç-å¯¼å ¥æ¨¡æ¿") public void importTemplate(HttpServletResponse response) { ExcelUtil<AfterSalesNearExpiryImportDto> util = new ExcelUtil<AfterSalesNearExpiryImportDto>(AfterSalesNearExpiryImportDto.class); util.importTemplateExcel(response, "临æå®å管çå¯¼å ¥æ¨¡æ¿"); } /** * 导åºä¸´æå®å */ @PostMapping("/export") @Operation(summary = "临æå®å管ç-导åº") @Log(title = "临æå®å管ç-导åº", businessType = BusinessType.EXPORT) public void export(HttpServletResponse response) { Page<AfterSalesNearExpiry> page = new Page<>(-1, -1); List<AfterSalesNearExpiry> list = afterSalesNearExpiryService.listPage(page, new AfterSalesNearExpiry()).getRecords(); List<AfterSalesNearExpiryExportDto> exportList = new ArrayList<>(); for (AfterSalesNearExpiry item : list) { AfterSalesNearExpiryExportDto dto = new AfterSalesNearExpiryExportDto(); BeanUtils.copyProperties(item, dto); if (item.getStatus() != null) { dto.setStatusName(String.valueOf(item.getStatus())); } exportList.add(dto); } ExcelUtil<AfterSalesNearExpiryExportDto> util = new ExcelUtil<AfterSalesNearExpiryExportDto>(AfterSalesNearExpiryExportDto.class); util.exportExcel(response, exportList, "临æå®å管ç"); } } src/main/java/com/ruoyi/aftersalesservice/controller/AfterSalesServiceController.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.aftersalesservice.dto.AfterSalesServiceExeclDto; import com.ruoyi.aftersalesservice.dto.AfterSalesServiceImportDto; import com.ruoyi.aftersalesservice.dto.AfterSalesServiceNewDto; import com.ruoyi.aftersalesservice.pojo.AfterSalesService; import com.ruoyi.aftersalesservice.service.AfterSalesServiceService; @@ -18,6 +19,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; import lombok.AllArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.util.CollectionUtils; @@ -150,4 +152,18 @@ return AjaxResult.success(afterSalesServiceService.countAfterSalesService()); } @PostMapping("/import") @Operation(summary = "å®åæå¡-åé¦ç»è®°å¯¼å ¥") @Log(title = "å®åæå¡-åé¦ç»è®°å¯¼å ¥", businessType = BusinessType.IMPORT) public AjaxResult importData(MultipartFile file) { return afterSalesServiceService.importData(file); } @PostMapping("/importTemplate") @Operation(summary = "å®åæå¡-åé¦ç»è®°å¯¼å ¥æ¨¡æ¿") public void importTemplate(HttpServletResponse response) { ExcelUtil<AfterSalesServiceImportDto> util = new ExcelUtil<AfterSalesServiceImportDto>(AfterSalesServiceImportDto.class); util.importTemplateExcel(response, "åé¦ç»è®°å¯¼å ¥æ¨¡æ¿"); } } src/main/java/com/ruoyi/aftersalesservice/dto/AfterSalesNearExpiryExportDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,60 @@ package com.ruoyi.aftersalesservice.dto; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDate; /** * 临æå®å管ç-å¯¼åº DTO * * @author :yys */ @Data public class AfterSalesNearExpiryExportDto { @Schema(description = "临æäº§ååç§°") @Excel(name = "临æäº§ååç§°") private String productName; @Schema(description = "äº§åæ¹å·") @Excel(name = "äº§åæ¹å·") private String batchNumber; @Schema(description = "ä¸´ææ¥æ") @Excel(name = "ä¸´ææ¥æ", width = 20, dateFormat = "yyyy-MM-dd") private LocalDate expireDate; @Schema(description = "åºåæ°é") @Excel(name = "åºåæ°é") private Integer stockQuantity; @Schema(description = "客æ·åç§°") @Excel(name = "客æ·åç§°") private String customerName; @Schema(description = "èç³»çµè¯") @Excel(name = "èç³»çµè¯") private String contactPhone; @Schema(description = "é®é¢æè¿°") @Excel(name = "é®é¢æè¿°") private String disRes; @Schema(description = "å¤çç¶æ") @Excel(name = "å¤çç¶æ", readConverterExp = "1=å¾ å¤ç,2=å·²å¤ç") private String statusName; @Schema(description = "å¤ç人") @Excel(name = "å¤ç人") private String disposeNickName; @Schema(description = "å¤çæ¥æ") @Excel(name = "å¤çæ¥æ", width = 20, dateFormat = "yyyy-MM-dd") private LocalDate disDate; @Schema(description = "å¤çç»æ") @Excel(name = "å¤çç»æ") private String disposeResult; } src/main/java/com/ruoyi/aftersalesservice/dto/AfterSalesNearExpiryImportDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,44 @@ package com.ruoyi.aftersalesservice.dto; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDate; /** * 临æå®å管ç-å¯¼å ¥ DTO * * @author :yys */ @Data public class AfterSalesNearExpiryImportDto { @Schema(description = "临æäº§ååç§°") @Excel(name = "临æäº§ååç§°") private String productName; @Schema(description = "äº§åæ¹å·") @Excel(name = "äº§åæ¹å·") private String batchNumber; @Schema(description = "ä¸´ææ¥æ") @Excel(name = "ä¸´ææ¥æ", width = 20, dateFormat = "yyyy-MM-dd") private LocalDate expireDate; @Schema(description = "åºåæ°é") @Excel(name = "åºåæ°é") private Integer stockQuantity; @Schema(description = "客æ·åç§°") @Excel(name = "客æ·åç§°") private String customerName; @Schema(description = "èç³»çµè¯") @Excel(name = "èç³»çµè¯") private String contactPhone; @Schema(description = "é®é¢æè¿°") @Excel(name = "é®é¢æè¿°") private String disRes; } src/main/java/com/ruoyi/aftersalesservice/dto/AfterSalesServiceImportDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,40 @@ package com.ruoyi.aftersalesservice.dto; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.Date; /** * åé¦ç»è®°-å¯¼å ¥ DTO * * @author :yys */ @Data public class AfterSalesServiceImportDto { @Schema(description = "客æ·åç§°") @Excel(name = "客æ·åç§°") private String customerName; @Schema(description = "å ³èéå®åå·") @Excel(name = "å ³èéå®åå·") private String salesContractNo; @Schema(description = "å®åç±»å") @Excel(name = "å®åç±»å") private String serviceType; @Schema(description = "ç´§æ¥ç¨åº¦") @Excel(name = "ç´§æ¥ç¨åº¦") private String urgency; @Schema(description = "å馿¥æ") @Excel(name = "å馿¥æ", width = 20, dateFormat = "yyyy-MM-dd") private Date feedbackDate; @Schema(description = "客æ·è¯æ±") @Excel(name = "客æ·è¯æ±") private String proDesc; } src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesNearExpiryService.java
@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.aftersalesservice.pojo.AfterSalesNearExpiry; import com.ruoyi.framework.web.domain.AjaxResult; import org.springframework.web.multipart.MultipartFile; /** * <br> @@ -23,4 +25,12 @@ IPage<AfterSalesNearExpiry> listPage(Page<AfterSalesNearExpiry> page, AfterSalesNearExpiry entity); /** * 临æå®å管ç-å¯¼å ¥ * * @param file excel æä»¶ * @return å¯¼å ¥ç»æï¼æå/å¤±è´¥æ¡æ°åé误æç»ï¼ */ AjaxResult importData(MultipartFile file); } src/main/java/com/ruoyi/aftersalesservice/service/AfterSalesServiceService.java
@@ -6,6 +6,8 @@ import com.ruoyi.aftersalesservice.dto.AfterSalesServiceNewDto; import com.ruoyi.aftersalesservice.dto.CountDto; import com.ruoyi.aftersalesservice.pojo.AfterSalesService; import com.ruoyi.framework.web.domain.AjaxResult; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -30,4 +32,12 @@ List<CountDto> countAfterSalesService(); /** * åé¦ç»è®°-å¯¼å ¥ * * @param file excel æä»¶ * @return å¯¼å ¥ç»æï¼æå/å¤±è´¥æ¡æ°åé误æç»ï¼ */ AjaxResult importData(MultipartFile file); } src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesNearExpiryServiceImpl.java
@@ -3,15 +3,24 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.aftersalesservice.dto.AfterSalesNearExpiryImportDto; import com.ruoyi.aftersalesservice.mapper.AfterSalesNearExpiryMapper; import com.ruoyi.aftersalesservice.pojo.AfterSalesNearExpiry; import com.ruoyi.aftersalesservice.service.AfterSalesNearExpiryService; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.web.domain.AjaxResult; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * <br> @@ -22,6 +31,7 @@ * @version 1.0 * @since 2026/03/02 14:46 */ @Slf4j @Service public class AfterSalesNearExpiryServiceImpl extends ServiceImpl<AfterSalesNearExpiryMapper, AfterSalesNearExpiry> implements AfterSalesNearExpiryService { @@ -86,4 +96,74 @@ public IPage<AfterSalesNearExpiry> listPage(Page<AfterSalesNearExpiry> page, AfterSalesNearExpiry entity) { return baseMapper.listPage(page, entity); } @Override public AjaxResult importData(MultipartFile file) { List<AfterSalesNearExpiryImportDto> rows; try { ExcelUtil<AfterSalesNearExpiryImportDto> util = new ExcelUtil<>(AfterSalesNearExpiryImportDto.class); rows = util.importExcel(file.getInputStream()); } catch (Exception e) { log.error("临æå®å管çå¯¼å ¥-è§£æexcel失败", e); return AjaxResult.error("è§£æExcel失败ï¼" + e.getMessage()); } if (CollectionUtils.isEmpty(rows)) { return AjaxResult.error("å¯¼å ¥æä»¶æ æ°æ®"); } int success = 0; List<String> errors = new ArrayList<>(); for (int i = 0; i < rows.size(); i++) { AfterSalesNearExpiryImportDto row = rows.get(i); int rowNo = i + 2; // é¦è¡ä¸ºè¡¨å¤´ try { if (StringUtils.isEmpty(trim(row.getProductName()))) { errors.add("第" + rowNo + "è¡ï¼ä¸´æäº§åå称为空"); continue; } if (StringUtils.isEmpty(trim(row.getBatchNumber()))) { errors.add("第" + rowNo + "è¡ï¼äº§åæ¹å·ä¸ºç©º"); continue; } if (row.getExpireDate() == null) { errors.add("第" + rowNo + "è¡ï¼ä¸´ææ¥æä¸ºç©º"); continue; } if (row.getStockQuantity() == null) { errors.add("第" + rowNo + "è¡ï¼åºåæ°é为空"); continue; } if (StringUtils.isEmpty(trim(row.getCustomerName()))) { errors.add("第" + rowNo + "è¡ï¼å®¢æ·å称为空"); continue; } AfterSalesNearExpiry entity = new AfterSalesNearExpiry(); entity.setProductName(trim(row.getProductName())); entity.setBatchNumber(trim(row.getBatchNumber())); entity.setExpireDate(row.getExpireDate()); entity.setStockQuantity(row.getStockQuantity()); entity.setCustomerName(trim(row.getCustomerName())); entity.setContactPhone(trim(row.getContactPhone())); entity.setDisRes(row.getDisRes()); add(entity); success++; } catch (Exception e) { log.error("临æå®å管çå¯¼å ¥ç¬¬{}è¡å¤±è´¥", rowNo, e); errors.add("第" + rowNo + "è¡ï¼" + e.getMessage()); } } AjaxResult result = AjaxResult.success(); result.put("totalCount", rows.size()); result.put("successCount", success); result.put("failCount", rows.size() - success); result.put("errors", errors); result.put("msg", "å¯¼å ¥å®æï¼æå " + success + " æ¡ï¼å¤±è´¥ " + (rows.size() - success) + " æ¡"); return result; } private String trim(String value) { return value == null ? null : value.trim(); } } src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java
@@ -1,22 +1,31 @@ package com.ruoyi.aftersalesservice.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.aftersalesservice.dto.AfterSalesServiceImportDto; import com.ruoyi.aftersalesservice.dto.AfterSalesServiceNewDto; import com.ruoyi.aftersalesservice.dto.CountDto; import com.ruoyi.aftersalesservice.mapper.AfterSalesServiceMapper; import com.ruoyi.aftersalesservice.pojo.AfterSalesService; import com.ruoyi.aftersalesservice.service.AfterSalesServiceService; import com.ruoyi.basic.mapper.CustomerMapper; import com.ruoyi.basic.pojo.Customer; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.project.system.domain.SysDept; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysDeptMapper; import com.ruoyi.project.system.domain.SysDictData; import com.ruoyi.project.system.mapper.SysDictDataMapper; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.sales.dto.SalesLedgerDto; import com.ruoyi.sales.mapper.SalesLedgerMapper; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.service.ISalesLedgerProductService; @@ -25,8 +34,12 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.stream.Collectors; @@ -45,6 +58,9 @@ private final ISalesLedgerProductService salesLedgerProductService; private final ISalesLedgerService salesLedgerService; private final com.ruoyi.sales.mapper.ShippingInfoMapper shippingInfoMapper; private final CustomerMapper customerMapper; private final SalesLedgerMapper salesLedgerMapper; private final SysDictDataMapper sysDictDataMapper; @Override public IPage<AfterSalesServiceNewDto> listPage(Page page, AfterSalesServiceNewDto afterSalesService) { @@ -138,4 +154,136 @@ return stringIntegerHashMap; } @Override public AjaxResult importData(MultipartFile file) { List<AfterSalesServiceImportDto> rows; try { ExcelUtil<AfterSalesServiceImportDto> util = new ExcelUtil<>(AfterSalesServiceImportDto.class); rows = util.importExcel(file.getInputStream()); } catch (Exception e) { log.error("åé¦ç»è®°å¯¼å ¥-è§£æexcel失败", e); return AjaxResult.error("è§£æExcel失败ï¼" + e.getMessage()); } if (CollectionUtils.isEmpty(rows)) { return AjaxResult.error("å¯¼å ¥æä»¶æ æ°æ®"); } Long tenantId = SecurityUtils.getLoginUser().getTenantId(); Long userId = SecurityUtils.getUserId(); int success = 0; List<String> errors = new ArrayList<>(); for (int i = 0; i < rows.size(); i++) { AfterSalesServiceImportDto row = rows.get(i); int rowNo = i + 2; // é¦è¡ä¸ºè¡¨å¤´ try { String customerName = trim(row.getCustomerName()); if (StringUtils.isEmpty(customerName)) { errors.add("第" + rowNo + "è¡ï¼å®¢æ·å称为空"); continue; } Customer customer = findCustomerByName(customerName, tenantId); if (customer == null) { errors.add("第" + rowNo + "è¡ï¼å®¢æ·[" + customerName + "]ä¸åå¨"); continue; } String serviceTypeName = trim(row.getServiceType()); String serviceTypeValue = dictValueByLabel("post_sale_waiting_list", serviceTypeName); if (StringUtils.isEmpty(serviceTypeValue)) { errors.add("第" + rowNo + "è¡ï¼å®åç±»å[" + serviceTypeName + "]ä¸åå¨"); continue; } String urgencyName = trim(row.getUrgency()); String urgencyValue = dictValueByLabel("degree_of_urgency", urgencyName); if (StringUtils.isEmpty(urgencyValue)) { errors.add("第" + rowNo + "è¡ï¼ç´§æ¥ç¨åº¦[" + urgencyName + "]ä¸åå¨"); continue; } Long salesLedgerId = null; String contractNo = trim(row.getSalesContractNo()); if (StringUtils.isNotEmpty(contractNo)) { SalesLedger ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>() .eq(SalesLedger::getSalesContractNo, contractNo) .eq(SalesLedger::getCustomerId, customer.getId()) .last("limit 1")); if (ledger == null) { ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>() .eq(SalesLedger::getSalesContractNo, contractNo) .last("limit 1")); } if (ledger == null) { errors.add("第" + rowNo + "è¡ï¼éå®åå·[" + contractNo + "]ä¸åå¨"); continue; } salesLedgerId = ledger.getId(); } AfterSalesServiceNewDto dto = new AfterSalesServiceNewDto(); dto.setCustomerName(customer.getCustomerName()); dto.setSalesLedgerId(salesLedgerId); dto.setServiceType(serviceTypeValue); dto.setUrgency(urgencyValue); dto.setProDesc(row.getProDesc()); dto.setFeedbackDate(row.getFeedbackDate() != null ? row.getFeedbackDate() : new Date()); dto.setCheckUserId(userId); dto.setProductModelIds(""); dto.setProductModelQuantities(""); if (addAfterSalesServiceDto(dto)) { success++; } else { errors.add("第" + rowNo + "è¡ï¼ä¿å失败"); } } catch (Exception e) { log.error("åé¦ç»è®°å¯¼å ¥ç¬¬{}è¡å¤±è´¥", rowNo, e); errors.add("第" + rowNo + "è¡ï¼" + e.getMessage()); } } AjaxResult result = AjaxResult.success(); result.put("totalCount", rows.size()); result.put("successCount", success); result.put("failCount", rows.size() - success); result.put("errors", errors); result.put("msg", "å¯¼å ¥å®æï¼æå " + success + " æ¡ï¼å¤±è´¥ " + (rows.size() - success) + " æ¡"); return result; } private String trim(String value) { return value == null ? null : value.trim(); } private Customer findCustomerByName(String name, Long tenantId) { List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>() .eq(Customer::getCustomerName, name)); if (CollectionUtils.isEmpty(customers)) { return null; } if (tenantId != null) { for (Customer c : customers) { if (tenantId.equals(c.getTenantId())) { return c; } } } return customers.get(0); } private String dictValueByLabel(String dictType, String label) { if (StringUtils.isEmpty(label)) { return null; } List<SysDictData> datas = sysDictDataMapper.selectDictDataByType(dictType); if (CollectionUtils.isEmpty(datas)) { return null; } for (SysDictData d : datas) { if (label.equals(d.getDictLabel())) { return d.getDictValue(); } } return null; } } src/main/java/com/ruoyi/basic/controller/ProductController.java
@@ -136,4 +136,14 @@ public void importProduct(HttpServletResponse response) { productService.exportImportTemplate(response); } /** * 导åºäº§åè§æ ¼åå· */ @PostMapping("/exportModel") @Operation(summary = "导åºäº§åè§æ ¼åå·") @Log(title = "产åè§æ ¼åå·å¯¼åº", businessType = BusinessType.EXPORT) public void exportModel(HttpServletResponse response, ProductDto productDto) { productModelService.exportProductModel(response, productDto); } } src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java
@@ -7,6 +7,7 @@ import com.ruoyi.basic.vo.ProductModelVo; import com.ruoyi.procurementrecord.bean.dto.ProcurementPageDto; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.util.List; import java.util.Map; @@ -27,4 +28,17 @@ ProductModel selectLatestRecord(); List<Map<String, Object>> getProductAndModelList(); /** * æäº§ååç§° + è§æ ¼åå·æ¥è¯¢äº§ååå· * * @param productName 产ååç§° * @param model è§æ ¼åå· * @return 产ååå·ï¼åç¬¬ä¸æ¡ï¼ */ @Select("select pm.id, pm.product_id, pm.model, pm.unit from product_model pm " + "left join product p on pm.product_id = p.id " + "where p.product_name = #{productName} and pm.model = #{model} " + "order by pm.id limit 1") ProductModel selectByProductNameAndModel(@Param("productName") String productName, @Param("model") String model); } src/main/java/com/ruoyi/basic/service/IProductModelService.java
@@ -7,6 +7,7 @@ import com.ruoyi.basic.dto.ProductModelDto; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.framework.web.domain.AjaxResult; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -35,4 +36,12 @@ IPage<ProductModel> modelListPage(Page page , ProductDto productDto); AjaxResult importProductModel(MultipartFile file); /** * 导åºäº§åè§æ ¼åå· * * @param response ååº * @param productDto 产åï¼æ idï¼ */ void exportProductModel(HttpServletResponse response, ProductDto productDto); } src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
@@ -18,6 +18,7 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.basic.dto.ProductModelExportDto; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.SalesLedgerProduct; @@ -27,6 +28,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Arrays; @@ -368,4 +371,20 @@ String trimmed = value.trim(); return trimmed.isEmpty() ? null : trimmed; } @Override public void exportProductModel(HttpServletResponse response, ProductDto productDto) { Page<ProductModel> page = new Page<>(-1, -1); List<ProductModel> list = modelListPage(page, productDto).getRecords(); List<ProductModelExportDto> exportList = new ArrayList<>(); for (ProductModel productModel : list) { ProductModelExportDto dto = new ProductModelExportDto(); dto.setProductCode(productModel.getProductCode()); dto.setModel(productModel.getModel()); dto.setUnit(productModel.getUnit()); exportList.add(dto); } ExcelUtil<ProductModelExportDto> util = new ExcelUtil<>(ProductModelExportDto.class); util.exportExcel(response, exportList, "产åè§æ ¼åå·"); } } src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
@@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.stock.dto.StockInRecordDto; import com.ruoyi.stock.dto.StockInRecordImportDto; import com.ruoyi.stock.service.StockInRecordService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; @@ -13,6 +15,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -81,4 +84,18 @@ return AjaxResult.success(); } @PostMapping("/import") @Log(title = "å ¥åºç®¡ç-å¯¼å ¥", businessType = BusinessType.IMPORT) @Operation(summary = "å ¥åºç®¡ç-å¯¼å ¥") public AjaxResult importData(MultipartFile file, String type) { return stockInRecordService.importData(file, type); } @PostMapping("/importTemplate") @Operation(summary = "å ¥åºç®¡ç-å¯¼å ¥æ¨¡æ¿") public void importTemplate(HttpServletResponse response) { ExcelUtil<StockInRecordImportDto> util = new ExcelUtil<StockInRecordImportDto>(StockInRecordImportDto.class); util.importTemplateExcel(response, "å ¥åºå¯¼å ¥æ¨¡æ¿"); } } src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
@@ -4,14 +4,17 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.stock.dto.StockOutRecordDto; import com.ruoyi.stock.dto.StockOutRecordImportDto; import com.ruoyi.stock.service.StockOutRecordService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import lombok.AllArgsConstructor; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpServletResponse; import java.util.List; @@ -87,4 +90,18 @@ return AjaxResult.success(); } @PostMapping("/import") @Log(title = "åºåºå°è´¦-å¯¼å ¥", businessType = BusinessType.IMPORT) @Operation(summary = "åºåºå°è´¦-å¯¼å ¥") public AjaxResult importData(MultipartFile file, String type) { return stockOutRecordService.importData(file, type); } @PostMapping("/importTemplate") @Operation(summary = "åºåºå°è´¦-å¯¼å ¥æ¨¡æ¿") public void importTemplate(HttpServletResponse response) { ExcelUtil<StockOutRecordImportDto> util = new ExcelUtil<StockOutRecordImportDto>(StockOutRecordImportDto.class); util.importTemplateExcel(response, "åºåºå¯¼å ¥æ¨¡æ¿"); } } src/main/java/com/ruoyi/stock/dto/StockInRecordImportDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,36 @@ package com.ruoyi.stock.dto; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; /** * å ¥åºç®¡ç-å¯¼å ¥ DTO * * @author :yys */ @Data public class StockInRecordImportDto { @Schema(description = "产å大类") @Excel(name = "产å大类") private String productName; @Schema(description = "è§æ ¼åå·") @Excel(name = "è§æ ¼åå·") private String model; @Schema(description = "æ¹å·") @Excel(name = "æ¹å·") private String batchNo; @Schema(description = "å ¥åºæ°é") @Excel(name = "å ¥åºæ°é") private BigDecimal stockInNum; @Schema(description = "夿³¨") @Excel(name = "夿³¨") private String remark; } src/main/java/com/ruoyi/stock/dto/StockOutRecordImportDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,36 @@ package com.ruoyi.stock.dto; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; /** * åºåºå°è´¦-å¯¼å ¥ DTO * * @author :yys */ @Data public class StockOutRecordImportDto { @Schema(description = "产å大类") @Excel(name = "产å大类") private String productName; @Schema(description = "è§æ ¼åå·") @Excel(name = "è§æ ¼åå·") private String model; @Schema(description = "æ¹å·") @Excel(name = "æ¹å·") private String batchNo; @Schema(description = "åºåºæ°é") @Excel(name = "åºåºæ°é") private BigDecimal stockOutNum; @Schema(description = "夿³¨") @Excel(name = "夿³¨") private String remark; } src/main/java/com/ruoyi/stock/service/StockInRecordService.java
@@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.stock.dto.StockInRecordDto; import com.ruoyi.stock.pojo.StockInRecord; import com.ruoyi.framework.web.domain.AjaxResult; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; import java.util.List; public interface StockInRecordService extends IService<StockInRecord> { @@ -25,4 +27,13 @@ int batchApprove(List<Long> ids, Integer approvalStatus); int batchReAudit(List<Long> ids); /** * å ¥åºç®¡ç-å¯¼å ¥ * * @param file excel æä»¶ * @param type å ¥åºç±»å 0-åæ ¼ 1-ä¸åæ ¼ * @return å¯¼å ¥ç»æï¼æå/å¤±è´¥æ¡æ°åé误æç»ï¼ */ AjaxResult importData(MultipartFile file, String type); } src/main/java/com/ruoyi/stock/service/StockOutRecordService.java
@@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.stock.dto.StockOutRecordDto; import com.ruoyi.stock.pojo.StockOutRecord; import com.ruoyi.framework.web.domain.AjaxResult; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; import java.util.List; /** @@ -31,4 +33,13 @@ void exportStockOutRecord(HttpServletResponse response, StockOutRecordDto stockOutRecordDto); int batchApprove(List<Long> ids, Integer approvalStatus); /** * åºåºå°è´¦-å¯¼å ¥ * * @param file excel æä»¶ * @param type åºåºç±»å 0-åæ ¼ 1-ä¸åæ ¼ * @return å¯¼å ¥ç»æï¼æå/å¤±è´¥æ¡æ°åé误æç»ï¼ */ AjaxResult importData(MultipartFile file, String type); } src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -14,6 +14,10 @@ import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.stock.dto.StockInRecordDto; import com.ruoyi.stock.dto.StockInRecordImportDto; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.stock.dto.StockInventoryDto; import com.ruoyi.stock.dto.StockUninventoryDto; import com.ruoyi.stock.execl.StockInRecordExportData; @@ -28,11 +32,13 @@ import com.ruoyi.stock.service.StockInRecordService; import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; import org.springframework.web.multipart.MultipartFile; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @Service @@ -43,6 +49,7 @@ private StockInventoryMapper stockInventoryMapper; private StockUninventoryMapper stockUninventoryMapper; private ProductionOrderPickMapper productionOrderPickMapper; private ProductModelMapper productModelMapper; @Override public IPage<StockInRecordDto> listPage(Page page, StockInRecordDto stockInRecordDto) { @@ -369,4 +376,74 @@ return ids.size(); } @Override public AjaxResult importData(MultipartFile file, String type) { List<StockInRecordImportDto> rows; try { ExcelUtil<StockInRecordImportDto> util = new ExcelUtil<>(StockInRecordImportDto.class); rows = util.importExcel(file.getInputStream()); } catch (Exception e) { return AjaxResult.error("è§£æExcel失败ï¼" + e.getMessage()); } if (CollectionUtils.isEmpty(rows)) { return AjaxResult.error("å¯¼å ¥æä»¶æ æ°æ®"); } String stockType = StringUtils.isEmpty(type) ? "0" : type.trim(); String recordType = "1".equals(stockType) ? StockInQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode() : StockInQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode(); int success = 0; List<String> errors = new ArrayList<>(); for (int i = 0; i < rows.size(); i++) { StockInRecordImportDto row = rows.get(i); int rowNo = i + 2; // é¦è¡ä¸ºè¡¨å¤´ try { String productName = trim(row.getProductName()); String model = trim(row.getModel()); if (StringUtils.isEmpty(productName)) { errors.add("第" + rowNo + "è¡ï¼äº§å大类为空"); continue; } if (StringUtils.isEmpty(model)) { errors.add("第" + rowNo + "è¡ï¼è§æ ¼åå·ä¸ºç©º"); continue; } if (row.getStockInNum() == null) { errors.add("第" + rowNo + "è¡ï¼å ¥åºæ°é为空"); continue; } ProductModel productModel = productModelMapper.selectByProductNameAndModel(productName, model); if (productModel == null) { errors.add("第" + rowNo + "è¡ï¼æªæ¾å°äº§å[" + productName + " / " + model + "]"); continue; } StockInRecordDto dto = new StockInRecordDto(); dto.setProductModelId(productModel.getId()); dto.setBatchNo(trim(row.getBatchNo())); dto.setStockInNum(row.getStockInNum()); dto.setRemark(row.getRemark()); dto.setType(stockType); dto.setRecordType(recordType); dto.setApprovalStatus(ReviewStatusEnum.PENDING_REVIEW.getCode()); add(dto); success++; } catch (Exception e) { errors.add("第" + rowNo + "è¡ï¼" + e.getMessage()); } } AjaxResult result = AjaxResult.success(); result.put("totalCount", rows.size()); result.put("successCount", success); result.put("failCount", rows.size() - success); result.put("errors", errors); result.put("msg", "å¯¼å ¥å®æï¼æå " + success + " æ¡ï¼å¤±è´¥ " + (rows.size() - success) + " æ¡"); return result; } private String trim(String value) { return value == null ? null : value.trim(); } } src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -17,6 +17,10 @@ import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.stock.dto.StockInventoryDto; import com.ruoyi.stock.dto.StockOutRecordDto; import com.ruoyi.stock.dto.StockOutRecordImportDto; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.stock.dto.StockUninventoryDto; import com.ruoyi.stock.execl.StockOutRecordExportData; import com.ruoyi.stock.mapper.StockInventoryMapper; @@ -31,7 +35,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.List; /** @@ -50,6 +56,7 @@ private final StockUninventoryMapper stockUninventoryMapper; private final AccountSalesCollectionMapper accountSalesCollectionMapper; private final AccountInvoiceApplicationMapper accountInvoiceApplicationMapper; private final ProductModelMapper productModelMapper; @Override public IPage<StockOutRecordDto> listPage(Page page, StockOutRecordDto stockOutRecordDto) { @@ -230,4 +237,74 @@ } return stockUninventoryMapper.selectOne(eq); } @Override public AjaxResult importData(MultipartFile file, String type) { List<StockOutRecordImportDto> rows; try { ExcelUtil<StockOutRecordImportDto> util = new ExcelUtil<>(StockOutRecordImportDto.class); rows = util.importExcel(file.getInputStream()); } catch (Exception e) { return AjaxResult.error("è§£æExcel失败ï¼" + e.getMessage()); } if (CollectionUtils.isEmpty(rows)) { return AjaxResult.error("å¯¼å ¥æä»¶æ æ°æ®"); } String stockType = StringUtils.isEmpty(type) ? "0" : type.trim(); String recordType = "1".equals(stockType) ? StockOutQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_OUT.getCode() : StockOutQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_OUT.getCode(); int success = 0; List<String> errors = new ArrayList<>(); for (int i = 0; i < rows.size(); i++) { StockOutRecordImportDto row = rows.get(i); int rowNo = i + 2; // é¦è¡ä¸ºè¡¨å¤´ try { String productName = trim(row.getProductName()); String model = trim(row.getModel()); if (StringUtils.isEmpty(productName)) { errors.add("第" + rowNo + "è¡ï¼äº§å大类为空"); continue; } if (StringUtils.isEmpty(model)) { errors.add("第" + rowNo + "è¡ï¼è§æ ¼åå·ä¸ºç©º"); continue; } if (row.getStockOutNum() == null) { errors.add("第" + rowNo + "è¡ï¼åºåºæ°é为空"); continue; } ProductModel productModel = productModelMapper.selectByProductNameAndModel(productName, model); if (productModel == null) { errors.add("第" + rowNo + "è¡ï¼æªæ¾å°äº§å[" + productName + " / " + model + "]"); continue; } StockOutRecordDto dto = new StockOutRecordDto(); dto.setProductModelId(productModel.getId()); dto.setBatchNo(trim(row.getBatchNo())); dto.setStockOutNum(row.getStockOutNum()); dto.setRemark(row.getRemark()); dto.setType(stockType); dto.setRecordType(recordType); dto.setApprovalStatus(ReviewStatusEnum.PENDING_REVIEW.getCode()); add(dto); success++; } catch (Exception e) { errors.add("第" + rowNo + "è¡ï¼" + e.getMessage()); } } AjaxResult result = AjaxResult.success(); result.put("totalCount", rows.size()); result.put("successCount", success); result.put("failCount", rows.size() - success); result.put("errors", errors); result.put("msg", "å¯¼å ¥å®æï¼æå " + success + " æ¡ï¼å¤±è´¥ " + (rows.size() - success) + " æ¡"); return result; } private String trim(String value) { return value == null ? null : value.trim(); } }