diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java index 1acc6b05a68cd2d93d59bc0b9a96bed730944f5a..6dc18c2be2d3849928ac69bfbf59bd013aa2335d 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java @@ -113,7 +113,7 @@ public class WebFrameworkUtils { return UserTypeEnum.ADMIN.getValue(); } if (request.getServletPath().startsWith(properties.getAppApi().getPrefix())) { - return UserTypeEnum.MEMBER.getValue(); + return UserTypeEnum.ADMIN.getValue();//暂时去掉会员的用户类型,全部都是管理员用户类型 } return null; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index 3f7dc6127b8e9c0b53083aa7b732f61de0a0e1d4..1f6600b734750f943cfbe5c1d688cd761f2b6ca5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -147,10 +147,10 @@ public class UserController { public void importTemplate(HttpServletResponse response) throws IOException { // 手动创建导出 demo List list = Arrays.asList( - UserImportExcelVO.builder().username("yunai").deptId(1L).email("yunai@iocoder.cn").mobile("15601691300") - .nickname("芋道").status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.MALE.getSex()).build(), - UserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300") - .nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build() + UserImportExcelVO.builder().username("falao").deptId(1L).email("666666@qq.com").mobile("15601691300") + .nickname("模板用户1").status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.MALE.getSex()).build(), + UserImportExcelVO.builder().username("fala").deptId(2L).email("666666@qq.com").mobile("15601701300") + .nickname("模板用户2").status(CommonStatusEnum.DISABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build() ); // 输出 ExcelUtils.write(response, "用户导入模板.xls", "用户列表", UserImportExcelVO.class, list); diff --git a/yudao-module-visit/pom.xml b/yudao-module-visit/pom.xml index d4f34c9e016103f29339dde0c53a62ca64ed725d..46fd7dff875dfc81518b9c72c3c9274eacd62594 100644 --- a/yudao-module-visit/pom.xml +++ b/yudao-module-visit/pom.xml @@ -41,6 +41,10 @@ cn.iocoder.boot yudao-spring-boot-starter-excel + + cn.iocoder.boot + yudao-spring-boot-starter-biz-data-permission + diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java index 7a9e296e8b2fca43182e1549ef549a855100df8d..2909cc8e6d46be61975426b00bf5c18af495a3aa 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/customerinfo/vo/CustomerInfoRespVO.java @@ -40,6 +40,29 @@ public class CustomerInfoRespVO { @ExcelProperty("所在地区") private String regionFullName; + @Schema(description = "详细地址", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("详细地址") + private String locationText; + + @Schema(description = "经度", requiredMode = Schema.RequiredMode.REQUIRED) + private BigDecimal longitude; + + @Schema(description = "纬度", requiredMode = Schema.RequiredMode.REQUIRED) + private BigDecimal latitude; + + @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("产品ID") + private String productIds; + + @Schema(description = "部门", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("部门") + @DictFormat("customer_dept") + private String department; + + @Schema(description = "静态图", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("静态图") + private String locationImage; + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") private LocalDateTime createTime; diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/ProductController.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/ProductController.java index 15fff174f4e1a54905fbc19379b9ccbb425b4b8f..4f304144b1031587e09e3be3e13da2eb90ad73b7 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/ProductController.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/ProductController.java @@ -1,5 +1,8 @@ package cn.iocoder.yudao.module.visit.controller.admin.product; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.module.system.enums.common.SexEnum; +import io.swagger.v3.oas.annotations.Parameters; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import org.springframework.validation.annotation.Validated; @@ -28,6 +31,7 @@ import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; import cn.iocoder.yudao.module.visit.controller.admin.product.vo.*; import cn.iocoder.yudao.module.visit.dal.dataobject.product.ProductDO; import cn.iocoder.yudao.module.visit.service.product.ProductService; +import org.springframework.web.multipart.MultipartFile; @Tag(name = "管理后台 - 产品") @RestController @@ -38,9 +42,6 @@ public class ProductController { @Resource private ProductService productService; - public ProductController(){ - System.out.println("生效"); - } @PostMapping("/create") @Operation(summary = "创建产品") @@ -96,4 +97,33 @@ public class ProductController { BeanUtils.toBean(list, ProductRespVO.class)); } + + + @GetMapping("/get-import-template") + @Operation(summary = "获得导入品种资料模板") + public void importTemplate(HttpServletResponse response) throws IOException { + // 手动创建导出 demo + List list = Arrays.asList( + ProductImportExcelVO.builder().productName("阿莫西林胶囊").specification("20x20mg").packageName("盒装") + .status(CommonStatusEnum.ENABLE.getStatus()).build(), + ProductImportExcelVO.builder().productName("阿莫西林胶囊").specification("10x50mg").packageName("袋装") + .status(CommonStatusEnum.DISABLE.getStatus()).build() + ); + // 输出 + ExcelUtils.write(response, "品种资料导入模板.xls", "品种资料列表", ProductImportExcelVO.class, list); + } + + @PostMapping("/import") + @Operation(summary = "导入品种资料") + @Parameters({ + @Parameter(name = "file", description = "Excel 文件", required = true), + @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") + }) + @PreAuthorize("@ss.hasPermission('system:product:import')") + public CommonResult importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { + List list = ExcelUtils.read(file, ProductImportExcelVO.class); + return success(productService.importProductList(list, updateSupport)); + } + } \ No newline at end of file diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductImportExcelVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductImportExcelVO.java new file mode 100644 index 0000000000000000000000000000000000000000..fcd36e0a6eb3abd0a9c44b86c30c96664804c08f --- /dev/null +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductImportExcelVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.visit.controller.admin.product.vo; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.system.enums.DictTypeConstants; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +/** + * 用户 Excel 导入 VO + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Accessors(chain = false) // 设置 chain = false,避免用户导入有问题 +public class ProductImportExcelVO { + + @ExcelProperty("品种名称") + private String productName; + + @ExcelProperty("规格") + private String specification; + + @ExcelProperty("包装信息") + private String packageName; + + @ExcelProperty(value = "状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.COMMON_STATUS) + private Integer status; + +} diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductImportRespVO.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductImportRespVO.java new file mode 100644 index 0000000000000000000000000000000000000000..b19ec75444ee8d5a8e6ecddad3a50cb7e45534d3 --- /dev/null +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/controller/admin/product/vo/ProductImportRespVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.visit.controller.admin.product.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Schema(description = "管理后台 - 用户导入 Response VO") +@Data +@Builder +public class ProductImportRespVO { + + @Schema(description = "创建成功的品种名称数组", requiredMode = Schema.RequiredMode.REQUIRED) + private List createProductNames; + + @Schema(description = "更新成功的品种名称数组", requiredMode = Schema.RequiredMode.REQUIRED) + private List updateProductNames; + + @Schema(description = "导入失败的品种名称用户集合,key 为品种名称,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED) + private Map failureProductNames; + +} diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/mysql/product/ProductMapper.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/mysql/product/ProductMapper.java index 403a09f5f1020899ebe8e812d8cc77266336458b..657310372b4a267e76ce22974b057a8bc9b12ee9 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/mysql/product/ProductMapper.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/dal/mysql/product/ProductMapper.java @@ -17,6 +17,10 @@ import cn.iocoder.yudao.module.visit.controller.admin.product.vo.*; @Mapper public interface ProductMapper extends BaseMapperX { + default ProductDO selectByProductParam(String productName, String specification, String packageName) { + return selectOne(ProductDO::getProductName, productName, ProductDO::getSpecification, specification, ProductDO::getPackageName, packageName); + } + default PageResult selectPage(ProductPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .likeIfPresent(ProductDO::getProductName, reqVO.getProductName()) diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/enums/ErrorCodeConstants.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/enums/ErrorCodeConstants.java index 9c4906075fa7c5df042ebf0a18aedc7e0552c27e..9a65768514f4f48ef243e3f62aad333281e59681 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/enums/ErrorCodeConstants.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/enums/ErrorCodeConstants.java @@ -11,6 +11,8 @@ public interface ErrorCodeConstants { // ========== 产品 ========== ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1001000001, "产品不存在"); + ErrorCode PRODUCT_IMPORT_LIST_IS_EMPTY = new ErrorCode(1001000002, "导入产品数据不能为空!"); + ErrorCode PRODUCT_PRODUCT_EXISTS = new ErrorCode(1001000002, "导入产品已存在!"); // ========== 客户信息 ========== ErrorCode CUSTOMER_INFO_NOT_EXISTS = new ErrorCode(1002000001, "客户信息不存在"); diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductService.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductService.java index 38657eae5c5f2c51c8fdd89e11ed06a9ffcab3fd..f36e1e8d7404bad473d7f88d89ebf273460e57da 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductService.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductService.java @@ -52,4 +52,11 @@ public interface ProductService { */ PageResult getProductPage(ProductPageReqVO pageReqVO); + /** + * 导入产品信息 + * + * @param list 分页查询 + * @return 产品分页 + */ + ProductImportRespVO importProductList(List list, Boolean updateSupport); } \ No newline at end of file diff --git a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductServiceImpl.java b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductServiceImpl.java index a34c84427908379c44ebb11502972dee6653ec96..f269ae3972a47bc5ac715e4c1a3334848a10dc9e 100644 --- a/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductServiceImpl.java +++ b/yudao-module-visit/src/main/java/cn/iocoder/yudao/module/visit/service/product/ProductServiceImpl.java @@ -1,7 +1,15 @@ package cn.iocoder.yudao.module.visit.service.product; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; +import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import javax.validation.ConstraintViolationException; + import org.springframework.validation.annotation.Validated; import org.springframework.transaction.annotation.Transactional; @@ -15,6 +23,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.visit.dal.mysql.product.ProductMapper; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.visit.enums.ErrorCodeConstants.*; /** @@ -71,4 +80,47 @@ public class ProductServiceImpl implements ProductService { return productMapper.selectPage(pageReqVO); } + @Override + @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入 + public ProductImportRespVO importProductList(List importProducts, Boolean isUpdateSupport) { + // 1 参数校验 + if (CollUtil.isEmpty(importProducts)) { + throw exception(PRODUCT_IMPORT_LIST_IS_EMPTY); + } + + // 2. 遍历,逐个创建 or 更新 + ProductImportRespVO respVO = ProductImportRespVO.builder().createProductNames(new ArrayList<>()) + .updateProductNames(new ArrayList<>()).failureProductNames(new LinkedHashMap<>()).build(); + importProducts.forEach(importProduct -> { + + // 2.1.1 校验,判断是否有不符合的原因 + try { + validateProductUnique(importProduct.getProductName(), importProduct.getSpecification(), importProduct.getPackageName()); + } catch (ServiceException ex) { + respVO.getFailureProductNames().put(importProduct.getProductName()+importProduct.getSpecification()+importProduct.getPackageName(), ex.getMessage()); + return; + } + + // 2.2.1 判断如果不存在,在进行插入 + ProductDO existProduct = productMapper.selectByProductParam(importProduct.getProductName(),importProduct.getSpecification(), importProduct.getPackageName()); + if (existProduct == null) { + productMapper.insert(BeanUtils.toBean(importProduct, ProductDO.class)); + respVO.getCreateProductNames().add(importProduct.getProductName()+importProduct.getSpecification()+importProduct.getPackageName()); + } + }); + return respVO; + } + + + private void validateProductUnique(String productName, String specification, String packageName) { + ProductPageReqVO productPageReqVO = new ProductPageReqVO(); + productPageReqVO.setProductName(productName); + productPageReqVO.setSpecification(specification); + productPageReqVO.setPackageName(packageName); + PageResult productDOPageResult = productMapper.selectPage(productPageReqVO); + if (productDOPageResult.getTotal() > 0) { + throw exception(PRODUCT_PRODUCT_EXISTS); + } + } + } \ No newline at end of file diff --git a/yudao-ui/yudao-ui-admin-vue3/package-lock.json b/yudao-ui/yudao-ui-admin-vue3/package-lock.json index ffe3a6d2664fc2472214627b17a09e657d580a53..15800d7eb2342e2a6e3d00ea19feed8bdf5d1ac2 100644 --- a/yudao-ui/yudao-ui-admin-vue3/package-lock.json +++ b/yudao-ui/yudao-ui-admin-vue3/package-lock.json @@ -31,6 +31,7 @@ "driver.js": "^1.3.1", "echarts": "^5.5.0", "echarts-wordcloud": "^2.1.0", + "element-china-area-data": "^6.1.0", "element-plus": "2.9.1", "fast-xml-parser": "^4.3.2", "highlight.js": "^11.9.0", @@ -7943,6 +7944,11 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/china-division": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/china-division/-/china-division-2.7.0.tgz", + "integrity": "sha512-4uUPAT+1WfqDh5jytq7omdCmHNk3j+k76zEG/2IqaGcYB90c2SwcixttcypdsZ3T/9tN1TTpBDoeZn+Yw/qBEA==" + }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -9423,6 +9429,14 @@ "dev": true, "license": "ISC" }, + "node_modules/element-china-area-data": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/element-china-area-data/-/element-china-area-data-6.1.0.tgz", + "integrity": "sha512-IkpcjwQv2A/2AxFiSoaISZ+oMw1rZCPUSOg5sOCwT5jKc96TaawmKZeY81xfxXsO0QbKxU5LLc6AirhG52hUmg==", + "dependencies": { + "china-division": "^2.7.0" + } + }, "node_modules/element-plus": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.9.1.tgz", diff --git a/yudao-ui/yudao-ui-admin-vue3/package.json b/yudao-ui/yudao-ui-admin-vue3/package.json index 307b915ec9cc665dfd329f427e766343abde149f..8aa2b56f968f1936391090bffa982b5bdef0dfbc 100644 --- a/yudao-ui/yudao-ui-admin-vue3/package.json +++ b/yudao-ui/yudao-ui-admin-vue3/package.json @@ -47,6 +47,7 @@ "driver.js": "^1.3.1", "echarts": "^5.5.0", "echarts-wordcloud": "^2.1.0", + "element-china-area-data": "^6.1.0", "element-plus": "2.9.1", "fast-xml-parser": "^4.3.2", "highlight.js": "^11.9.0", diff --git a/yudao-ui/yudao-ui-admin-vue3/src/api/visit/product/index.ts b/yudao-ui/yudao-ui-admin-vue3/src/api/visit/product/index.ts index 51dea7117a03f3ab7905e3c6f281ce5679625146..ea00260c0c862e30369203e9a8bf64c100a2e812 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/api/visit/product/index.ts +++ b/yudao-ui/yudao-ui-admin-vue3/src/api/visit/product/index.ts @@ -40,4 +40,9 @@ export const ProductApi = { exportProduct: async (params) => { return await request.download({ url: `/visit/product/export-excel`, params }) }, + + // 下载产品信息导入模板 + importProductTemplate: async () => { + return await request.download({ url: '/visit/product/get-import-template' }) + } } diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/index.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/index.vue index 76944948c9da42b4044f72571e224cc289a3bc08..a8688861a2fe2cdf3e7fa51c92f7bab4988d783f 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/index.vue +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/system/user/index.vue @@ -70,14 +70,14 @@ > 新增 - - - - - - - - + + 导入 + diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue index 78d4987c91a40b6c4a4d81bdad64aa23dc70624e..abbb28350ef9ce736ba0699aef740a9044bcc484 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/customerinfo/CustomerInfoForm.vue @@ -26,30 +26,49 @@ /> - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -73,7 +92,7 @@ \ No newline at end of file + diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/ProductImportForm.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/ProductImportForm.vue new file mode 100644 index 0000000000000000000000000000000000000000..aa11235e712cb2fccffc61fede30319093383311 --- /dev/null +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/ProductImportForm.vue @@ -0,0 +1,134 @@ + + diff --git a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/index.vue b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/index.vue index b25762df73ea3df06bdd6a9f9521ce5a1086f7ab..2a5e803751a81405fb1bac909031806e33c724aa 100644 --- a/yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/index.vue +++ b/yudao-ui/yudao-ui-admin-vue3/src/views/visit/product/index.vue @@ -72,6 +72,14 @@ > 新增 + + 导入 + + +