|
|
@@ -1,18 +1,28 @@
|
|
|
package org.dromara.product.controller;
|
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
import cn.hutool.core.lang.tree.Tree;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
import jakarta.validation.constraints.*;
|
|
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
|
|
-import org.dromara.product.domain.ProductBaseAudit;
|
|
|
+import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
+import org.dromara.easyes.core.biz.EsPageInfo;
|
|
|
+import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
|
|
|
+import org.dromara.product.domain.*;
|
|
|
import org.dromara.product.domain.bo.*;
|
|
|
import org.dromara.product.domain.vo.*;
|
|
|
+import org.dromara.product.esmapper.ProductEsMapper;
|
|
|
import org.dromara.product.service.*;
|
|
|
+import org.dromara.system.api.RemoteTaxCodeService;
|
|
|
+import org.dromara.system.api.domain.vo.RemoteTaxCodeVo;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
|
|
@@ -24,12 +34,31 @@ import org.dromara.common.core.validate.AddGroup;
|
|
|
import org.dromara.common.core.validate.EditGroup;
|
|
|
import org.dromara.common.log.enums.BusinessType;
|
|
|
import org.dromara.common.excel.utils.ExcelUtil;
|
|
|
+import org.dromara.common.excel.core.ExcelResult;
|
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+import org.dromara.product.listener.ProductBaseImportListener;
|
|
|
+import org.dromara.product.listener.ProductImageImportListener;
|
|
|
+import org.dromara.product.listener.ProductFullImportListener;
|
|
|
+import org.dromara.product.domain.vo.ProductImageImportVo;
|
|
|
+import org.dromara.product.domain.vo.ProductFullImportVo;
|
|
|
+import org.dromara.product.domain.vo.ProductImageExportVo;
|
|
|
|
|
|
/**
|
|
|
* 产品基础信息
|
|
|
* 前端访问路由地址为:/product/base
|
|
|
*
|
|
|
+ * 商品导入导出接口说明:
|
|
|
+ * 1. /importTemplate - 下载商品基本信息导入模板
|
|
|
+ * 2. /importData - 导入商品基本信息
|
|
|
+ * 3. /importFullTemplate - 下载商品完整信息导入模板(包含图片和详情)
|
|
|
+ * 4. /importFullData - 导入商品完整信息(包含图片和详情)
|
|
|
+ * 5. /importImageTemplate - 下载商品图片详情导入模板
|
|
|
+ * 6. /importImageData - 导入商品图片详情
|
|
|
+ * 7. /export - 导出商品列表(包含图片和详情)
|
|
|
+ * 8. /exportImage - 导出商品图片详情
|
|
|
+ *
|
|
|
* @author LionLi
|
|
|
* @date 2025-12-11
|
|
|
*/
|
|
|
@@ -55,6 +84,15 @@ public class ProductBaseController extends BaseController {
|
|
|
|
|
|
private final IProductBaseAuditService productBaseAuditService;
|
|
|
|
|
|
+ private final IProductPhotosService productPhotosService;
|
|
|
+
|
|
|
+ private final IProductClassificationDiyService productClassificationDiyService;
|
|
|
+
|
|
|
+ private final ProductEsMapper productEsMapper;
|
|
|
+
|
|
|
+
|
|
|
+ @DubboReference
|
|
|
+ private final RemoteTaxCodeService remoteTaxCodeService;
|
|
|
/**
|
|
|
* 查询产品基础信息列表
|
|
|
*/
|
|
|
@@ -72,16 +110,7 @@ public class ProductBaseController extends BaseController {
|
|
|
return R.ok(productBaseService.getProductStatusCount());
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 导出产品基础信息列表
|
|
|
- */
|
|
|
- //@SaCheckPermission("product:base:export")
|
|
|
- @Log(title = "产品基础信息", businessType = BusinessType.EXPORT)
|
|
|
- @PostMapping("/export")
|
|
|
- public void export(ProductBaseBo bo, HttpServletResponse response) {
|
|
|
- List<ProductBaseVo> list = productBaseService.queryList(bo);
|
|
|
- ExcelUtil.exportExcel(list, "产品基础信息", ProductBaseVo.class, response);
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 获取产品基础信息详细信息
|
|
|
@@ -316,5 +345,185 @@ public class ProductBaseController extends BaseController {
|
|
|
return R.ok(isDuplicate);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 导出产品基础信息列表
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:export")
|
|
|
+ @Log(title = "产品基础信息", businessType = BusinessType.EXPORT)
|
|
|
+ @PostMapping("/export")
|
|
|
+ public void export(@RequestBody ProductBaseBo bo, HttpServletResponse response) {
|
|
|
+
|
|
|
+ LambdaEsQueryWrapper<ProductBaseVo> productBaseVoLambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();
|
|
|
+ productBaseVoLambdaEsQueryWrapper.ge(ObjectUtil.isNotEmpty(bo.getProductNo()), ProductBaseVo::getProductNo, bo.getProductNo());
|
|
|
+ productBaseVoLambdaEsQueryWrapper.orderByAsc(ProductBaseVo::getProductNo);
|
|
|
+ //获取全部税收编码
|
|
|
+ List<RemoteTaxCodeVo> remoteTaxCodeVos = remoteTaxCodeService.selectAll(new RemoteTaxCodeVo());
|
|
|
+ Map<Long, String> remoteTaxCodeMap = remoteTaxCodeVos.stream().filter(item -> ObjectUtil.isNotEmpty(item.getTaxationNo())).collect(Collectors.toMap(RemoteTaxCodeVo::getId, RemoteTaxCodeVo::getTaxationNo));
|
|
|
+ //获取品牌
|
|
|
+ List<ProductBrand> productBrands = productBrandService.list(Wrappers.<ProductBrand>lambdaQuery());
|
|
|
+ Map<Long, String> productBrandMap = productBrands.stream().filter(item -> ObjectUtil.isNotEmpty(item.getBrandNo())).collect(Collectors.toMap(ProductBrand::getId, ProductBrand::getBrandNo));
|
|
|
+ //获取分类
|
|
|
+ List<ProductCategory> productCategories = productCategoryService.list(Wrappers.<ProductCategory>lambdaQuery());
|
|
|
+ Map<Long, String> productCategoryMap = productCategories.stream().filter(item -> ObjectUtil.isNotEmpty(item.getCategoryNo())).collect(Collectors.toMap(ProductCategory::getId, ProductCategory::getCategoryNo));
|
|
|
+ //获取单位
|
|
|
+ List<ProductUnit> productUnits = productUnitService.list(Wrappers.<ProductUnit>lambdaQuery());
|
|
|
+ Map<Long, String> productUnitMap = productUnits.stream().filter(item -> ObjectUtil.isNotEmpty(item.getUnitNo())).collect(Collectors.toMap(ProductUnit::getId, ProductUnit::getUnitNo));
|
|
|
+ EsPageInfo<ProductBaseVo> esPageInfo = productEsMapper.pageQuery(productBaseVoLambdaEsQueryWrapper, 1, 1000);
|
|
|
+
|
|
|
+ List<ProductBaseVo> list = esPageInfo.getList();
|
|
|
+ // 转换为导入Vo格式以便导出(包含图片和详情)
|
|
|
+ List<ProductFullImportVo> exportList = list.stream().map(vo -> {
|
|
|
+ ProductFullImportVo exportVo = new ProductFullImportVo();
|
|
|
+ exportVo.setProductNo(vo.getProductNo());
|
|
|
+ exportVo.setProductName(vo.getItemName());
|
|
|
+ exportVo.setCategoryNo(productCategoryMap.get(vo.getBottomCategoryId()));
|
|
|
+ exportVo.setCategoryName(vo.getBottomCategoryName());
|
|
|
+ exportVo.setSpecificationsCode(vo.getSpecificationsCode());
|
|
|
+ exportVo.setProductDescription(vo.getProductDescription());
|
|
|
+ exportVo.setPromotionTitle(vo.getPromotionTitle());
|
|
|
+ exportVo.setProductExplain(vo.getProductExplain());
|
|
|
+ exportVo.setBarCoding(vo.getBarCoding());
|
|
|
+ exportVo.setInvoiceName(vo.getInvoiceName());
|
|
|
+ exportVo.setInvoiceSpecs(vo.getInvoiceSpecs());
|
|
|
+ exportVo.setTaxRate(vo.getTaxRate());
|
|
|
+ exportVo.setIsTaxIncluded("是");
|
|
|
+ exportVo.setBrandNo(productBrandMap.get(vo.getBrandId()));
|
|
|
+ exportVo.setBrandName(vo.getBrandName());
|
|
|
+ exportVo.setUnitNo(ObjectUtil.isNotEmpty(vo.getUnitId()) ? productUnitMap.get(Long.valueOf(vo.getUnitId())) : "");
|
|
|
+ exportVo.setUnitName(vo.getUnitName());
|
|
|
+ exportVo.setReferenceLink(vo.getReferenceLink());
|
|
|
+ exportVo.setMarketPrice(vo.getMarketPrice());
|
|
|
+ exportVo.setMemberPrice(vo.getMemberPrice());
|
|
|
+ exportVo.setMinSellingPrice(vo.getMinSellingPrice());
|
|
|
+ exportVo.setPurchasingPrice(vo.getPurchasingPrice());
|
|
|
+ exportVo.setMaxPurchasePrice(vo.getMaxPurchasePrice());
|
|
|
+ exportVo.setShelfStatus(vo.getProductStatus() != null && vo.getProductStatus() == 1 ? "1" : "0");
|
|
|
+ exportVo.setMainImage(vo.getProductImage());
|
|
|
+ exportVo.setTaxCode(remoteTaxCodeMap.get(vo.getTaxationId()));
|
|
|
+ //获取自定义属性
|
|
|
+ ProductClassificationDiy one = productClassificationDiyService.getOne(Wrappers.<ProductClassificationDiy>lambdaQuery()
|
|
|
+ .eq(ProductClassificationDiy::getProductId, vo.getId())
|
|
|
+ .orderByDesc(ProductClassificationDiy::getCreateTime)
|
|
|
+ .last("limit 1")
|
|
|
+ );
|
|
|
+ if(ObjectUtil.isNotEmpty(one)){
|
|
|
+ exportVo.setCustomAttributeName(one.getAttributeKey());
|
|
|
+ exportVo.setCustomAttributeValue(one.getAttributeValue());
|
|
|
+ }
|
|
|
+ return exportVo;
|
|
|
+ }).toList();
|
|
|
+ ExcelUtil.exportExcel(exportList, "产品基础信息", ProductFullImportVo.class, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取导入模板(包含基本信息)
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:import")
|
|
|
+ @PostMapping("/importTemplate")
|
|
|
+ public void importTemplate(HttpServletResponse response) {
|
|
|
+ ExcelUtil.exportExcel(new ArrayList<>(), "商品导入模板", ProductBaseImportVo.class, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取商品完整信息导入模板(包含图片和详情)
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:import")
|
|
|
+ @PostMapping("/importFullTemplate")
|
|
|
+ public void importFullTemplate(HttpServletResponse response) {
|
|
|
+ ExcelUtil.exportExcel(new ArrayList<>(), "商品完整信息导入模板", ProductFullImportVo.class, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导入商品基础信息
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:import")
|
|
|
+ @Log(title = "商品基础信息", businessType = BusinessType.IMPORT)
|
|
|
+ @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
|
|
+ public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
|
|
|
+ ExcelResult<ProductBaseImportVo> result = ExcelUtil.importExcel(
|
|
|
+ file.getInputStream(),
|
|
|
+ ProductBaseImportVo.class,
|
|
|
+ new ProductBaseImportListener(productBaseService, remoteTaxCodeService)
|
|
|
+ );
|
|
|
+ return R.ok(result.getAnalysis());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导入商品完整信息(包含图片和详情)
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:import")
|
|
|
+ @Log(title = "商品完整信息", businessType = BusinessType.IMPORT)
|
|
|
+ @PostMapping(value = "/importFullData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
|
|
+ public R<Void> importFullData(@RequestPart("file") MultipartFile file) throws Exception {
|
|
|
+ ExcelResult<ProductFullImportVo> result = ExcelUtil.importExcel(
|
|
|
+ file.getInputStream(),
|
|
|
+ ProductFullImportVo.class,
|
|
|
+ new ProductFullImportListener(productBaseService, remoteTaxCodeService)
|
|
|
+ );
|
|
|
+ return R.ok(result.getAnalysis());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取商品图片详情导入模板
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:import")
|
|
|
+ @PostMapping("/importImageTemplate")
|
|
|
+ public void importImageTemplate(HttpServletResponse response) {
|
|
|
+ ExcelUtil.exportExcel(new ArrayList<>(), "商品图片详情导入模板", ProductImageImportVo.class, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导入商品图片详情
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:import")
|
|
|
+ @Log(title = "商品图片详情", businessType = BusinessType.IMPORT)
|
|
|
+ @PostMapping(value = "/importImageData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
|
|
+ public R<Void> importImageData(@RequestPart("file") MultipartFile file) throws Exception {
|
|
|
+ ExcelResult<ProductImageImportVo> result = ExcelUtil.importExcel(
|
|
|
+ file.getInputStream(),
|
|
|
+ ProductImageImportVo.class,
|
|
|
+ new ProductImageImportListener(productBaseService)
|
|
|
+ );
|
|
|
+ return R.ok(result.getAnalysis());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导出商品图片详情
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:export")
|
|
|
+ @Log(title = "商品图片详情", businessType = BusinessType.EXPORT)
|
|
|
+ @PostMapping("/exportImage")
|
|
|
+ public void exportImage(@RequestBody ProductBaseBo bo, HttpServletResponse response) {
|
|
|
+ LambdaEsQueryWrapper<ProductBaseVo> productBaseVoLambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();
|
|
|
+ productBaseVoLambdaEsQueryWrapper.ge(ObjectUtil.isNotEmpty(bo.getProductNo()), ProductBaseVo::getProductNo, bo.getProductNo());
|
|
|
+ productBaseVoLambdaEsQueryWrapper.orderByAsc(ProductBaseVo::getProductNo);
|
|
|
+ EsPageInfo<ProductBaseVo> esPageInfo = productEsMapper.pageQuery(productBaseVoLambdaEsQueryWrapper, 1, 1000);
|
|
|
+ List<ProductBaseVo> list = esPageInfo.getList();
|
|
|
+ List<ProductImageExportVo> exportList = list.stream().map(vo -> {
|
|
|
+ ProductImageExportVo exportVo = new ProductImageExportVo();
|
|
|
+ exportVo.setProductNo(vo.getProductNo());
|
|
|
+ exportVo.setMainImage(vo.getProductImage());
|
|
|
+ if(ObjectUtil.isNotEmpty(vo.getImageUrl())||ObjectUtil.isNotEmpty(vo.getPcDetail())){
|
|
|
+ ProductPhotosVo productPhotosVo = productPhotosService.queryById(vo.getId());
|
|
|
+ if(ObjectUtil.isNotEmpty(productPhotosVo)){
|
|
|
+ exportVo.setProductDetail(productPhotosVo.getProductDetailsPc());
|
|
|
+ exportVo.setCarouselImages(productPhotosVo.getImageUrl());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return exportVo;
|
|
|
+ }).toList();
|
|
|
+ ExcelUtil.exportExcel(exportList, "商品图片详情", ProductImageExportVo.class, response);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导出商品完整信息(包含图片和详情)
|
|
|
+ */
|
|
|
+ //@SaCheckPermission("product:base:export")
|
|
|
+ @Log(title = "商品完整信息", businessType = BusinessType.EXPORT)
|
|
|
+ @PostMapping("/exportFull")
|
|
|
+ public void exportFull(@RequestBody ProductBaseBo bo, HttpServletResponse response) {
|
|
|
+ export(bo, response);
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
}
|