diff --git a/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/ProductInfoController.java b/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/ProductInfoController.java index f3ce3ae..23ef128 100644 --- a/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/ProductInfoController.java +++ b/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/ProductInfoController.java @@ -95,7 +95,7 @@ public class ProductInfoController { @Operation(summary = "产品信息导入模板") public void importTemplate(HttpServletResponse response) throws IOException { // 输出 - ExcelUtils.write(response, "产品信息导入模板.xls", "产品信息", ProductInfoExcelVO.class, null); + ExcelUtils.write(response, "产品信息导入模板.xlsx", "产品信息", ProductInfoExcelVO.class, null); } @PostMapping("/import") @Operation(summary = "导入生产制单") @@ -116,7 +116,7 @@ public class ProductInfoController { pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); List list = productInfoService.getProductInfoPage(pageReqVO).getList(); // 导出 Excel - ExcelUtils.write(response, "产品资料 .xls", "数据", ProductInfoRespVO.class,list); + ExcelUtils.write(response, "产品资料.xlsx", "数据", ProductInfoRespVO.class,list); } } \ No newline at end of file diff --git a/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/vo/ProductInfoExcelVO.java b/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/vo/ProductInfoExcelVO.java index f2341a7..bc5c463 100644 --- a/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/vo/ProductInfoExcelVO.java +++ b/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/vo/ProductInfoExcelVO.java @@ -1,14 +1,17 @@ package cn.hangtag.module.oms.controller.admin.productinfo.vo; import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ContentStyle; +import com.alibaba.excel.annotation.write.style.HeadFontStyle; +import com.alibaba.excel.annotation.write.style.HeadStyle; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; - -import java.time.LocalDateTime; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; /** * 产品信息导入 Excel VO @@ -17,16 +20,48 @@ import java.time.LocalDateTime; @Builder @AllArgsConstructor @NoArgsConstructor -@Accessors(chain = false) // 设置 chain = false,避免数据导入有问题 +@Accessors(chain = false) // 保持 chain = false 避免导入数据异常 public class ProductInfoExcelVO { - @ExcelProperty("产品编码") + @Schema(description = "产品编码") + @ExcelProperty("*产品编码") + @HeadFontStyle(color = Font.COLOR_RED) private String code; - @ExcelProperty("产品名称") + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("*产品名称") + @HeadFontStyle(color = Font.COLOR_RED) private String name; + + @Schema(description = "产品简介") + @ExcelProperty("产品简介") + @HeadFontStyle(color = Font.COLOR_NORMAL) + private String introduction; + + @Schema(description = "产品规格-宽") + @ExcelProperty("产品规格-宽") + @HeadFontStyle(color = Font.COLOR_NORMAL) + private String specWidth; + + @Schema(description = "产品规格-高") + @ExcelProperty("产品规格-高") + private String specHeight; + + @Schema(description = "产品规格-厚度") + @ExcelProperty("产品规格-厚度") + private String specThickness; + + @Schema(description = "材质(颜色)") + @ExcelProperty("材质(颜色)") + private String material; + + @Schema(description = "品牌名称") @ExcelProperty("品牌名称") private String brandName; -} + + @Schema(description = "备注") + @ExcelProperty("备注") + private String remarks; +} \ No newline at end of file diff --git a/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/vo/ProductInfoRespVO.java b/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/vo/ProductInfoRespVO.java index 2365d26..53f48cd 100644 --- a/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/vo/ProductInfoRespVO.java +++ b/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/controller/admin/productinfo/vo/ProductInfoRespVO.java @@ -1,5 +1,6 @@ package cn.hangtag.module.oms.controller.admin.productinfo.vo; +import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @@ -15,7 +16,7 @@ import com.alibaba.excel.annotation.*; @ExcelIgnoreUnannotated public class ProductInfoRespVO { - @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "3187") + @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "102") @ExcelProperty("id") private Long id; @@ -23,35 +24,32 @@ public class ProductInfoRespVO { @ExcelProperty("产品编码") private String code; - @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "示例名称") @ExcelProperty("产品名称") private String name; @Schema(description = "封面") @ExcelProperty("封面") + @ColumnWidth(10) private String cover; - @Schema(description = "品牌", example = "12523") - @ExcelProperty("品牌") + private Long brandId; - @Schema(description = "客户组别id oms_customer_group", example = "12523,1233") private String customerGroupId; @Schema(description = "客户组别 oms_customer_group name", example = "vip") + @ExcelProperty("客户组别") private String customerGroupName; - @Schema(description = "产品类型id", example = "26002") - @ExcelProperty("产品类型id") + private Long productTypeId; - @Schema(description = "设计稿id", example = "29789") - @ExcelProperty("设计稿id") + private String draftDesignDataId; - @Schema(description = "设计稿列表") - @ExcelProperty("设计稿列表") + private String draftDesignList; @Schema(description = "启用状态") @@ -73,10 +71,12 @@ public class ProductInfoRespVO { @Schema(description = "详情介绍") @ExcelProperty("详情介绍") + @ColumnWidth(100) private String details; @Schema(description = "简述") @ExcelProperty("简述") + @ColumnWidth(60) private String summary; /** @@ -86,6 +86,9 @@ public class ProductInfoRespVO { /** * 默认售价 */ + @Schema(description = "默认售价") + @ExcelProperty("默认售价") + @ColumnWidth(60) private BigDecimal sellingPrice; /** * 币种 字典 currency_type value diff --git a/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/service/productinfo/ProductInfoServiceImpl.java b/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/service/productinfo/ProductInfoServiceImpl.java index c2bd9c2..4f26802 100644 --- a/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/service/productinfo/ProductInfoServiceImpl.java +++ b/hangtag-module-oms/hangtag-module-oms-biz/src/main/java/cn/hangtag/module/oms/service/productinfo/ProductInfoServiceImpl.java @@ -23,6 +23,8 @@ import cn.hangtag.module.oms.dal.mysql.productprocess.ProductProcessMapper; import cn.hangtag.module.oms.serialnumber.CodingRulesUtils; import cn.hangtag.module.oms.service.brand.BrandService; import cn.hangtag.module.oms.service.draftdesigndata.DraftDesignDataService; +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.LFUCache; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -185,7 +187,34 @@ public class ProductInfoServiceImpl implements ProductInfoService { public PageResult getProductInfoPage(ProductInfoPageReqVO pageReqVO) { PageResult productInfoDOPageResult = productInfoMapper.selectPage(pageReqVO); List list = productInfoDOPageResult.getList(); - List resList = wrapperRespVO(list); + List resList = new ArrayList<>(); + Set groupIds = new HashSet<>(); + Set productTypeIds = new HashSet<>(); + Set brandIds = new HashSet<>(); + for (ProductInfoDO infoDO : list) { + String customerGroupId = infoDO.getCustomerGroupId(); + if(FuncUtil.isNotEmpty(customerGroupId)){ + groupIds.add(customerGroupId); + } + Long productTypeId = infoDO.getProductTypeId(); + if(FuncUtil.isNotEmpty(productTypeId)){ + productTypeIds.add(productTypeId); + } + Long brandId = infoDO.getBrandId(); + if(FuncUtil.isNotEmpty(brandId)){ + brandIds.add(brandId); + } + } + initBrandNameCache(brandIds); + initCustomerGroupNameCache(groupIds); + initProductTypeNameCache(productTypeIds); + list.forEach(productInfoDO -> { + ProductInfoRespVO vo = BeanUtils.toBean(productInfoDO, ProductInfoRespVO.class); + wrapperBrandName(vo); + wrapperProductTypeName(vo); + wrapperCustomerGroupName(vo); + resList.add(vo); + }); return new PageResult<>(resList, productInfoDOPageResult.getTotal()); } @@ -256,10 +285,20 @@ public class ProductInfoServiceImpl implements ProductInfoService { } + private static LFUCache brandIdCache = CacheUtil.newLFUCache(10000, 1000 * 60 *30); @Override public String importExcel(List list) { List newList = new ArrayList<>(); + + LambdaQueryWrapper brandDOLambdaQueryWrapper = new LambdaQueryWrapper<>(); + brandDOLambdaQueryWrapper.select(BrandDO::getName,BrandDO::getId,BrandDO::getCode); + brandDOLambdaQueryWrapper.eq(BaseDO::getDeleted,false); + List brandDOS = brandMapper.selectList(brandDOLambdaQueryWrapper); + for (BrandDO brandDO : brandDOS) { + brandIdCache.put(brandDO.getName(),brandDO.getId()); + } + for (int i = 0; i < list.size(); i++) { ProductInfoExcelVO excelVO = list.get(i); ProductInfoDO productInfo = new ProductInfoDO(); @@ -279,10 +318,17 @@ public class ProductInfoServiceImpl implements ProductInfoService { productInfo.setCode(code); productInfo.setTemplateType("2"); if(FuncUtil.isNotEmpty(brandName)){ - BrandDO brandDO = brandService.getBrandByName(brandName); - if(FuncUtil.isNotEmpty(brandDO)){ - productInfo.setBrandId(brandDO.getId()); + Long brandId = brandIdCache.get(brandName); + if(FuncUtil.isNotEmpty(brandId)){ + productInfo.setBrandId(brandId); + }else { + BrandDO brandDO = brandService.getBrandByName(brandName); + if(FuncUtil.isNotEmpty(brandDO)){ + productInfo.setBrandId(brandDO.getId()); + brandIdCache.put(brandName,brandDO.getId()); + } } + } newList.add(productInfo); } @@ -328,11 +374,44 @@ public class ProductInfoServiceImpl implements ProductInfoService { } return vo; } + private static LFUCache CustomerGroupNameCache = CacheUtil.newLFUCache(10000, 1000 * 60 * 60); + private ProductInfoRespVO wrapperCustomerGroupName(ProductInfoRespVO vo){ if(FuncUtil.isNotEmpty(vo)){ if(FuncUtil.isNotEmpty(vo.getCustomerGroupId())){ + String s = CustomerGroupNameCache.get(vo.getCustomerGroupId()); + if(FuncUtil.isNotEmpty(s)){ + vo.setCustomerGroupName(s); + + }else { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(CustomerGroupDO::getId, FuncUtil.toStrList(vo.getCustomerGroupId())); + wrapper.eq(BaseDO::getDeleted,false); + List groupDOS = customerGroupMapper.selectList(wrapper); + String name = null; + if(FuncUtil.isNotEmpty(groupDOS)){ + List names = new ArrayList<>(); + for (CustomerGroupDO groupDO : groupDOS) { + if(names.contains(groupDO.getName())){ + continue; + } + names.add(groupDO.getName()); + } + name = String.join(",", names); + } + vo.setCustomerGroupName(name); + CustomerGroupNameCache.put(vo.getCustomerGroupId(), name); + } + + } + } + return vo; + } + private void initCustomerGroupNameCache(Set ids){ + if (FuncUtil.isNotEmpty(ids)) { + for (String db : ids) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - wrapper.in(CustomerGroupDO::getId, FuncUtil.toStrList(vo.getCustomerGroupId())); + wrapper.in(CustomerGroupDO::getId, FuncUtil.toStrList(db)); wrapper.eq(BaseDO::getDeleted,false); List groupDOS = customerGroupMapper.selectList(wrapper); String name = null; @@ -346,31 +425,66 @@ public class ProductInfoServiceImpl implements ProductInfoService { } name = String.join(",", names); } - vo.setCustomerGroupName(name); + CustomerGroupNameCache.put(db, name); } } - return vo; + } + + private static LFUCache ProductTypeNameCache = CacheUtil.newLFUCache(10000, 1000 * 60 * 60); private ProductInfoRespVO wrapperProductTypeName(ProductInfoRespVO vo){ if(FuncUtil.isNotEmpty(vo)){ if(FuncUtil.isNotEmpty(vo.getProductTypeId())){ - ProductTypeDO productTypeDO = productTypeMapper.selectById(vo.getProductTypeId()); - if(FuncUtil.isNotEmpty(productTypeDO)){ - vo.setProductTypeName(productTypeDO.getLabel()); + String s = ProductTypeNameCache.get(vo.getProductTypeId()); + if (FuncUtil.isNotEmpty(s)){ + vo.setProductTypeName(s); + }else { + ProductTypeDO productTypeDO = productTypeMapper.selectById(vo.getProductTypeId()); + if(FuncUtil.isNotEmpty(productTypeDO)){ + vo.setProductTypeName(productTypeDO.getLabel()); + ProductTypeNameCache.put(vo.getProductTypeId(), vo.getProductTypeName()); + } } + } } return vo; } + private void initProductTypeNameCache(Set ids){ + if(FuncUtil.isNotEmpty(ids)){ + List dos = productTypeMapper.selectBatchIds(ids); + for (ProductTypeDO db : dos) { + brandNameCache.put(db.getId(), db.getLabel()); + } + } + } + + + private static LFUCache brandNameCache = CacheUtil.newLFUCache(10000, 1000 * 60 * 60); private ProductInfoRespVO wrapperBrandName(ProductInfoRespVO vo){ if(FuncUtil.isNotEmpty(vo)){ if(FuncUtil.isNotEmpty(vo.getBrandId())){ - BrandDO brandDO = brandMapper.selectById(vo.getBrandId()); - if(FuncUtil.isNotEmpty(brandDO)){ - vo.setBrandName(brandDO.getName()); + String s = brandNameCache.get(vo.getBrandId()); + if(FuncUtil.isNotEmpty(s)){ + vo.setBrandName(s); + }else { + BrandDO brandDO = brandMapper.selectById(vo.getBrandId()); + if(FuncUtil.isNotEmpty(brandDO)){ + vo.setBrandName(brandDO.getName()); + brandNameCache.put(vo.getBrandId(), brandDO.getName()); + } } } } return vo; } + private void initBrandNameCache(Set ids){ + if(FuncUtil.isNotEmpty(ids)){ + List brandDOS = brandMapper.selectBatchIds(ids); + for (BrandDO brandDO : brandDOS) { + brandNameCache.put(brandDO.getId(), brandDO.getName()); + } + } + + } } \ No newline at end of file diff --git a/hangtag-ui/hangtag-ui-admin/src/views/oms/productinfo/index.vue b/hangtag-ui/hangtag-ui-admin/src/views/oms/productinfo/index.vue index b4cf4a7..e3f6b01 100644 --- a/hangtag-ui/hangtag-ui-admin/src/views/oms/productinfo/index.vue +++ b/hangtag-ui/hangtag-ui-admin/src/views/oms/productinfo/index.vue @@ -199,6 +199,7 @@ import download from '@/utils/download' import {ProductInfoApi, ProductInfoVO} from '@/api/oms/productinfo' import ProductInfoForm from './ProductInfoForm.vue' +import ProductInfoExcelImport from './ProductInfoExcelImport.vue' import {ProductTypeApi} from "@/api/base/producttype"; import {buildQuery} from "@/utils/queryUtil"; @@ -288,10 +289,12 @@ const handleExport = async () => { // 发起导出 exportLoading.value = true const data = await ProductInfoApi.exportProductInfo(queryParams) - download.excel(data, '产品资料 .xls') + download.excel(data, '产品资料.xlsx') + message.success('导出完成'); } catch { } finally { exportLoading.value = false + } } const previewDraftDesign = (id) => { @@ -342,6 +345,7 @@ const importSuccess = (res)=>{ const downloadTemplate = ()=>{ ProductInfoApi.downloadTemplate().then(res => { download.excel(res, '产品导入模板.xlsx') + message.success("下载完成") }) } const handleImport = () => {