From 09722c0cd60785adda33cde16d4fa2f9b1d8f2b3 Mon Sep 17 00:00:00 2001 From: JeromeSoar <jeromesoar@mail.com> Date: Sun, 24 Apr 2022 10:12:31 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E3=80=90=E4=BF=AE=E5=A4=8D=E3=80=91mall=20?= =?UTF-8?q?=E7=88=B6=E6=A8=A1=E5=9D=97=20artifactId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- yudao-module-mall/pom.xml | 2 +- yudao-module-mall/yudao-module-market-api/pom.xml | 2 +- yudao-module-mall/yudao-module-market-biz/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 0ba239d5d..e3c5072ab 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ <module>yudao-module-system</module> <module>yudao-module-infra</module> <module>yudao-module-pay</module> - <module>yudao-module-market</module> + <module>yudao-module-mall</module> </modules> <name>${project.artifactId}</name> diff --git a/yudao-module-mall/pom.xml b/yudao-module-mall/pom.xml index 448986c6e..b13dc68f6 100644 --- a/yudao-module-mall/pom.xml +++ b/yudao-module-mall/pom.xml @@ -9,7 +9,7 @@ </parent> <modelVersion>4.0.0</modelVersion> - <artifactId>yudao-module-market</artifactId> + <artifactId>yudao-module-mall</artifactId> <packaging>pom</packaging> <name>${project.artifactId}</name> diff --git a/yudao-module-mall/yudao-module-market-api/pom.xml b/yudao-module-mall/yudao-module-market-api/pom.xml index c83179632..fef3428fc 100644 --- a/yudao-module-mall/yudao-module-market-api/pom.xml +++ b/yudao-module-mall/yudao-module-market-api/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> - <artifactId>yudao-module-market</artifactId> <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-module-mall</artifactId> <version>${revision}</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/yudao-module-mall/yudao-module-market-biz/pom.xml b/yudao-module-mall/yudao-module-market-biz/pom.xml index 0e3a0490e..e7fa33e9d 100644 --- a/yudao-module-mall/yudao-module-market-biz/pom.xml +++ b/yudao-module-mall/yudao-module-market-biz/pom.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> - <artifactId>yudao-module-market</artifactId> <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-module-mall</artifactId> <version>${revision}</version> </parent> <modelVersion>4.0.0</modelVersion> From 4e67b6bbcfb353ac8da1df71bb1342deeac337fb Mon Sep 17 00:00:00 2001 From: JeromeSoar <jeromesoar@mail.com> Date: Sun, 24 Apr 2022 14:42:51 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=95=86=E5=93=81=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mall.sql | 55 ++++ yudao-module-mall/pom.xml | 2 + .../yudao-module-product-api/pom.xml | 27 ++ .../module/product/api/package-info.java | 4 + .../product/enums/ErrorCodeConstants.java | 14 + .../yudao-module-product-biz/pom.xml | 67 +++++ .../admin/category/CategoryController.java | 100 +++++++ .../admin/category/vo/CategoryBaseVO.java | 42 +++ .../category/vo/CategoryCreateReqVO.java | 14 + .../admin/category/vo/CategoryExcelVO.java | 48 +++ .../category/vo/CategoryExportReqVO.java | 30 ++ .../admin/category/vo/CategoryPageReqVO.java | 35 +++ .../admin/category/vo/CategoryRespVO.java | 19 ++ .../category/vo/CategoryUpdateReqVO.java | 18 ++ .../convert/category/CategoryConvert.java | 34 +++ .../dal/dataobject/category/CategoryDO.java | 58 ++++ .../dal/mysql/category/CategoryMapper.java | 37 +++ .../yudao/module/product/package-info.java | 7 + .../service/category/CategoryService.java | 70 +++++ .../service/category/CategoryServiceImpl.java | 82 +++++ .../category/CategoryServiceImplTest.java | 194 ++++++++++++ .../src/test/resources/sql/clean.sql | 1 + .../src/test/resources/sql/create_tables.sql | 17 ++ yudao-server/pom.xml | 13 +- .../src/api/mall/product/category.js | 54 ++++ .../src/views/mall/product/category/index.vue | 281 ++++++++++++++++++ 26 files changed, 1319 insertions(+), 4 deletions(-) create mode 100644 sql/mall.sql create mode 100644 yudao-module-mall/yudao-module-product-api/pom.xml create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/cn/iocoder/yudao/module/product/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java create mode 100644 yudao-module-mall/yudao-module-product-biz/pom.xml create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExcelVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExportReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/CategoryConvert.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/CategoryDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/CategoryMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql create mode 100644 yudao-ui-admin/src/api/mall/product/category.js create mode 100644 yudao-ui-admin/src/views/mall/product/category/index.vue diff --git a/sql/mall.sql b/sql/mall.sql new file mode 100644 index 000000000..390044e06 --- /dev/null +++ b/sql/mall.sql @@ -0,0 +1,55 @@ +/* + Navicat Premium Data Transfer + + Source Server : 127.0.0.1 + Source Server Type : MySQL + Source Server Version : 80026 + Source Host : localhost:3306 + Source Schema : ruoyi-vue-pro + + Target Server Type : MySQL + Target Server Version : 80026 + File Encoding : 65001 + + Date: 05/02/2022 00:50:30 +*/ +SET +FOREIGN_KEY_CHECKS = 0; +SET NAMES utf8mb4; + +-- ---------------------------- +-- Table structure for product_category +-- ---------------------------- +DROP TABLE IF EXISTS `product_category`; +CREATE TABLE `product_category` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', + `pid` bigint NOT NULL COMMENT '父分类编号', + `name` varchar(255) NOT NULL COMMENT '分类名称', + `icon` varchar(100) DEFAULT '#' COMMENT '分类图标', + `banner_url` varchar(255) NOT NULL COMMENT '分类图片', + `sort` int NOT NULL DEFAULT '0' COMMENT '分类排序', + `description` varchar(1024) NOT NULL COMMENT '分类描述', + `status` tinyint NOT NULL COMMENT '开启状态', + `creator` varchar(64) DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB COMMENT='商品分类'; + +-- TODO 父级菜单的 id 处理 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) VALUES (2000, '商城', '', 1, 1, 0, '/mall', 'merchant', NULL, 0); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) VALUES (2001, '商品管理', '', 1, 1, 2000, 'product', 'dict', NULL, 0); +-- 菜单 SQL +INSERT INTO `system_menu`(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) VALUES ('商品分类管理', '', 2, 0, 2001, 'category', '', 'mall/product/category/index', 0); +-- 按钮父菜单ID +SELECT @parentId := LAST_INSERT_ID(); +-- 按钮 SQL +INSERT INTO `system_menu`(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) VALUES ('商品分类查询', 'product:category:query', 3, 1, @parentId, '', '', '', 0); +INSERT INTO `system_menu`(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) VALUES ('商品分类创建', 'product:category:create', 3, 2, @parentId, '', '', '', 0); +INSERT INTO `system_menu`(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) VALUES ('商品分类更新', 'product:category:update', 3, 3, @parentId, '', '', '', 0); +INSERT INTO `system_menu`(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) VALUES ('商品分类删除', 'product:category:delete', 3, 4, @parentId, '', '', '', 0); +INSERT INTO `system_menu`(`name`, `permission`, `menu_type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`) VALUES ('商品分类导出', 'product:category:export', 3, 5, @parentId, '', '', '', 0); diff --git a/yudao-module-mall/pom.xml b/yudao-module-mall/pom.xml index b13dc68f6..866874852 100644 --- a/yudao-module-mall/pom.xml +++ b/yudao-module-mall/pom.xml @@ -21,6 +21,8 @@ <modules> <module>yudao-module-market-api</module> <module>yudao-module-market-biz</module> + <module>yudao-module-product-api</module> + <module>yudao-module-product-biz</module> </modules> </project> diff --git a/yudao-module-mall/yudao-module-product-api/pom.xml b/yudao-module-mall/yudao-module-product-api/pom.xml new file mode 100644 index 000000000..7eb38008a --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/pom.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-module-mall</artifactId> + <version>${revision}</version> + </parent> + + <artifactId>yudao-module-product-api</artifactId> + <packaging>jar</packaging> + + <name>${project.artifactId}</name> + <description> + product 模块 API,暴露给其它模块调用 + </description> + + <dependencies> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-common</artifactId> + </dependency> + </dependencies> + +</project> \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-api/src/main/cn/iocoder/yudao/module/product/api/package-info.java b/yudao-module-mall/yudao-module-product-api/src/main/cn/iocoder/yudao/module/product/api/package-info.java new file mode 100644 index 000000000..b19092853 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/cn/iocoder/yudao/module/product/api/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位 + */ +package cn.iocoder.yudao.module.product.api; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-api/src/main/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java new file mode 100644 index 000000000..b8c671fc5 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * product 错误码枚举类 + * <p> + * product 系统,使用 1-008-000-000 段 + */ +public interface ErrorCodeConstants { + + // ========== 商品分类相关 1008001000============ + ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在"); +} diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml new file mode 100644 index 000000000..a06f8937c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/pom.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-module-mall</artifactId> + <version>${revision}</version> + </parent> + + <artifactId>yudao-module-product-biz</artifactId> + <packaging>jar</packaging> + + <name>${project.artifactId}</name> + <description> + product 模块,主要实现商品相关功能 + 例如:品牌、商品分类、spu、sku等功能。 + </description> + + + <dependencies> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-module-product-api</artifactId> + <version>${revision}</version> + </dependency> + + <!-- 业务组件 --> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId> + </dependency> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId> + </dependency> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> + </dependency> + + <!-- Web 相关 --> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-spring-boot-starter-excel</artifactId> + </dependency> + + <!-- DB 相关 --> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-spring-boot-starter-mybatis</artifactId> + </dependency> + + <!-- Test 测试相关 --> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-spring-boot-starter-test</artifactId> + </dependency> + + </dependencies> + +</project> \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java new file mode 100644 index 000000000..346b3177a --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java @@ -0,0 +1,100 @@ +package cn.iocoder.yudao.module.product.controller.admin.category; + +import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.annotations.*; + +import javax.validation.constraints.*; +import javax.validation.*; +import javax.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; + +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; + +import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; +import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; +import cn.iocoder.yudao.module.product.service.category.CategoryService; + +@Api(tags = "管理后台 - 商品分类") +@RestController +@RequestMapping("/product/category") +@Validated +public class CategoryController { + + @Resource + private CategoryService categoryService; + + @PostMapping("/create") + @ApiOperation("创建商品分类") + @PreAuthorize("@ss.hasPermission('product:category:create')") + public CommonResult<Long> createCategory(@Valid @RequestBody CategoryCreateReqVO createReqVO) { + return success(categoryService.createCategory(createReqVO)); + } + + @PutMapping("/update") + @ApiOperation("更新商品分类") + @PreAuthorize("@ss.hasPermission('product:category:update')") + public CommonResult<Boolean> updateCategory(@Valid @RequestBody CategoryUpdateReqVO updateReqVO) { + categoryService.updateCategory(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除商品分类") + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('product:category:delete')") + public CommonResult<Boolean> deleteCategory(@RequestParam("id") Long id) { + categoryService.deleteCategory(id); + return success(true); + } + + @GetMapping("/get") + @ApiOperation("获得商品分类") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('product:category:query')") + public CommonResult<CategoryRespVO> getCategory(@RequestParam("id") Long id) { + CategoryDO category = categoryService.getCategory(id); + return success(CategoryConvert.INSTANCE.convert(category)); + } + + @GetMapping("/list") + @ApiOperation("获得商品分类列表") + @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @PreAuthorize("@ss.hasPermission('product:category:query')") + public CommonResult<List<CategoryRespVO>> getCategoryList(@RequestParam("ids") Collection<Long> ids) { + List<CategoryDO> list = categoryService.getCategoryList(ids); + return success(CategoryConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @ApiOperation("获得商品分类分页") + @PreAuthorize("@ss.hasPermission('product:category:query')") + public CommonResult<PageResult<CategoryRespVO>> getCategoryPage(@Valid CategoryPageReqVO pageVO) { + PageResult<CategoryDO> pageResult = categoryService.getCategoryPage(pageVO); + return success(CategoryConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @ApiOperation("导出商品分类 Excel") + @PreAuthorize("@ss.hasPermission('product:category:export')") + @OperateLog(type = EXPORT) + public void exportCategoryExcel(@Valid CategoryExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List<CategoryDO> list = categoryService.getCategoryList(exportReqVO); + // 导出 Excel + List<CategoryExcelVO> datas = CategoryConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "商品分类.xls", "数据", CategoryExcelVO.class, datas); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java new file mode 100644 index 000000000..82f2ba09d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +/** +* 商品分类 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class CategoryBaseVO { + + @ApiModelProperty(value = "父分类编号", required = true, example = "1") + @NotNull(message = "父分类编号不能为空") + private Long pid; + + @ApiModelProperty(value = "分类名称", required = true, example = "办公文具") + @NotNull(message = "分类名称不能为空") + private String name; + + @ApiModelProperty(value = "分类图标") + private String icon; + + @ApiModelProperty(value = "分类图片", required = true) + @NotNull(message = "分类图片不能为空") + private String bannerUrl; + + @ApiModelProperty(value = "分类排序", required = true, example = "1") + @NotNull(message = "分类排序不能为空") + private Integer sort; + + @ApiModelProperty(value = "分类描述", required = true, example = "描述") + @NotNull(message = "分类描述不能为空") + private String description; + + @ApiModelProperty(value = "开启状态", required = true, example = "0") + @NotNull(message = "开启状态不能为空") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryCreateReqVO.java new file mode 100644 index 000000000..ce583f08b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +@ApiModel("管理后台 - 商品分类创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CategoryCreateReqVO extends CategoryBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExcelVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExcelVO.java new file mode 100644 index 000000000..ae754e42d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExcelVO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; + +import com.alibaba.excel.annotation.ExcelProperty; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + + +/** + * 商品分类 Excel VO + * + * @author 芋道源码 + */ +@Data +public class CategoryExcelVO { + + @ExcelProperty("分类编号") + private Long id; + + @ExcelProperty("父分类编号") + private Long pid; + + @ExcelProperty("分类名称") + private String name; + + @ExcelProperty("分类图标") + private String icon; + + @ExcelProperty("分类图片") + private String bannerUrl; + + @ExcelProperty("分类排序") + private Integer sort; + + @ExcelProperty("分类描述") + private String description; + + @ExcelProperty(value = "开启状态", converter = DictConvert.class) + @DictFormat("common_status") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中 + private Integer status; + + @ExcelProperty("创建时间") + private Date createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExportReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExportReqVO.java new file mode 100644 index 000000000..c1e23b3ed --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExportReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel(value = "管理后台 - 商品分类 Excel 导出 Request VO", description = "参数和 CategoryPageReqVO 是一致的") +@Data +public class CategoryExportReqVO { + + @ApiModelProperty(value = "分类名称", example = "办公文具") + private String name; + + @ApiModelProperty(value = "开启状态", example = "0") + private Integer status; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryPageReqVO.java new file mode 100644 index 000000000..d824b8bd8 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryPageReqVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("管理后台 - 商品分类分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CategoryPageReqVO extends PageParam { + + @ApiModelProperty(value = "分类名称", example = "办公文具") + private String name; + + @ApiModelProperty(value = "开启状态", example = "0") + private Integer status; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryRespVO.java new file mode 100644 index 000000000..e7d0b2238 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; + +@ApiModel("管理后台 - 商品分类 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CategoryRespVO extends CategoryBaseVO { + + @ApiModelProperty(value = "分类编号", required = true, example = "2") + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryUpdateReqVO.java new file mode 100644 index 000000000..13ee83c1e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryUpdateReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +@ApiModel("管理后台 - 商品分类更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CategoryUpdateReqVO extends CategoryBaseVO { + + @ApiModelProperty(value = "分类编号", required = true, example = "2") + @NotNull(message = "分类编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/CategoryConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/CategoryConvert.java new file mode 100644 index 000000000..2b2cfe99c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/CategoryConvert.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.product.convert.category; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; + +/** + * 商品分类 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface CategoryConvert { + + CategoryConvert INSTANCE = Mappers.getMapper(CategoryConvert.class); + + CategoryDO convert(CategoryCreateReqVO bean); + + CategoryDO convert(CategoryUpdateReqVO bean); + + CategoryRespVO convert(CategoryDO bean); + + List<CategoryRespVO> convertList(List<CategoryDO> list); + + PageResult<CategoryRespVO> convertPage(PageResult<CategoryDO> page); + + List<CategoryExcelVO> convertList02(List<CategoryDO> list); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/CategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/CategoryDO.java new file mode 100644 index 000000000..bbebfc11c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/CategoryDO.java @@ -0,0 +1,58 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.category; + +import lombok.*; +import java.util.*; +import com.baomidou.mybatisplus.annotation.*; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; + +/** + * 商品分类 DO + * + * @author 芋道源码 + */ +@TableName("product_category") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CategoryDO extends BaseDO { + + /** + * 分类编号 + */ + @TableId + private Long id; + /** + * 父分类编号 + */ + private Long pid; + /** + * 分类名称 + */ + private String name; + /** + * 分类图标 + */ + private String icon; + /** + * 分类图片 + */ + private String bannerUrl; + /** + * 分类排序 + */ + private Integer sort; + /** + * 分类描述 + */ + private String description; + /** + * 开启状态 + * + * 枚举 {@link TODO common_status 对应的类} + */ + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/CategoryMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/CategoryMapper.java new file mode 100644 index 000000000..109f1ff54 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/CategoryMapper.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.product.dal.mysql.category; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 商品分类 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface CategoryMapper extends BaseMapperX<CategoryDO> { + + default PageResult<CategoryDO> selectPage(CategoryPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX<CategoryDO>() + .likeIfPresent(CategoryDO::getName, reqVO.getName()) + .eqIfPresent(CategoryDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(CategoryDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc(CategoryDO::getId)); + } + + default List<CategoryDO> selectList(CategoryExportReqVO reqVO) { + return selectList(new LambdaQueryWrapperX<CategoryDO>() + .likeIfPresent(CategoryDO::getName, reqVO.getName()) + .eqIfPresent(CategoryDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(CategoryDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc(CategoryDO::getId)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java new file mode 100644 index 000000000..4e80cc2bc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java @@ -0,0 +1,7 @@ +/** + * TODO + * + * @author JeromeSoar + * @since 2022-04-24 + */ +package cn.iocoder.yudao.module.product; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java new file mode 100644 index 000000000..ff5f520fa --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.product.service.category; + +import java.util.*; +import javax.validation.*; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +/** + * 商品分类 Service 接口 + * + * @author 芋道源码 + */ +public interface CategoryService { + + /** + * 创建商品分类 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createCategory(@Valid CategoryCreateReqVO createReqVO); + + /** + * 更新商品分类 + * + * @param updateReqVO 更新信息 + */ + void updateCategory(@Valid CategoryUpdateReqVO updateReqVO); + + /** + * 删除商品分类 + * + * @param id 编号 + */ + void deleteCategory(Long id); + + /** + * 获得商品分类 + * + * @param id 编号 + * @return 商品分类 + */ + CategoryDO getCategory(Long id); + + /** + * 获得商品分类列表 + * + * @param ids 编号 + * @return 商品分类列表 + */ + List<CategoryDO> getCategoryList(Collection<Long> ids); + + /** + * 获得商品分类分页 + * + * @param pageReqVO 分页查询 + * @return 商品分类分页 + */ + PageResult<CategoryDO> getCategoryPage(CategoryPageReqVO pageReqVO); + + /** + * 获得商品分类列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 商品分类列表 + */ + List<CategoryDO> getCategoryList(CategoryExportReqVO exportReqVO); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java new file mode 100644 index 000000000..873bad297 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.product.service.category; + +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; +import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; + +/** + * 商品分类 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class CategoryServiceImpl implements CategoryService { + + @Resource + private CategoryMapper categoryMapper; + + @Override + public Long createCategory(CategoryCreateReqVO createReqVO) { + // 插入 + CategoryDO category = CategoryConvert.INSTANCE.convert(createReqVO); + categoryMapper.insert(category); + // 返回 + return category.getId(); + } + + @Override + public void updateCategory(CategoryUpdateReqVO updateReqVO) { + // 校验存在 + this.validateCategoryExists(updateReqVO.getId()); + // 更新 + CategoryDO updateObj = CategoryConvert.INSTANCE.convert(updateReqVO); + categoryMapper.updateById(updateObj); + } + + @Override + public void deleteCategory(Long id) { + // 校验存在 + this.validateCategoryExists(id); + // 删除 + categoryMapper.deleteById(id); + } + + private void validateCategoryExists(Long id) { + if (categoryMapper.selectById(id) == null) { + throw exception(CATEGORY_NOT_EXISTS); + } + } + + @Override + public CategoryDO getCategory(Long id) { + return categoryMapper.selectById(id); + } + + @Override + public List<CategoryDO> getCategoryList(Collection<Long> ids) { + return categoryMapper.selectBatchIds(ids); + } + + @Override + public PageResult<CategoryDO> getCategoryPage(CategoryPageReqVO pageReqVO) { + return categoryMapper.selectPage(pageReqVO); + } + + @Override + public List<CategoryDO> getCategoryList(CategoryExportReqVO exportReqVO) { + return categoryMapper.selectList(exportReqVO); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImplTest.java new file mode 100644 index 000000000..c0ef7e572 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImplTest.java @@ -0,0 +1,194 @@ +package cn.iocoder.yudao.module.product.service.category; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; +import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link CategoryServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(CategoryServiceImpl.class) +public class CategoryServiceImplTest extends BaseDbUnitTest { + + @Resource + private CategoryServiceImpl categoryService; + + @Resource + private CategoryMapper categoryMapper; + + @Test + public void testCreateCategory_success() { + // 准备参数 + CategoryCreateReqVO reqVO = randomPojo(CategoryCreateReqVO.class); + + // 调用 + Long categoryId = categoryService.createCategory(reqVO); + // 断言 + assertNotNull(categoryId); + // 校验记录的属性是否正确 + CategoryDO category = categoryMapper.selectById(categoryId); + assertPojoEquals(reqVO, category); + } + + @Test + public void testUpdateCategory_success() { + // mock 数据 + CategoryDO dbCategory = randomPojo(CategoryDO.class); + categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 + // 准备参数 + CategoryUpdateReqVO reqVO = randomPojo(CategoryUpdateReqVO.class, o -> { + o.setId(dbCategory.getId()); // 设置更新的 ID + }); + + // 调用 + categoryService.updateCategory(reqVO); + // 校验是否更新正确 + CategoryDO category = categoryMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, category); + } + + @Test + public void testUpdateCategory_notExists() { + // 准备参数 + CategoryUpdateReqVO reqVO = randomPojo(CategoryUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> categoryService.updateCategory(reqVO), CATEGORY_NOT_EXISTS); + } + + @Test + public void testDeleteCategory_success() { + // mock 数据 + CategoryDO dbCategory = randomPojo(CategoryDO.class); + categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbCategory.getId(); + + // 调用 + categoryService.deleteCategory(id); + // 校验数据不存在了 + assertNull(categoryMapper.selectById(id)); + } + + @Test + public void testDeleteCategory_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> categoryService.deleteCategory(id), CATEGORY_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetCategoryPage() { + // mock 数据 + CategoryDO dbCategory = randomPojo(CategoryDO.class, o -> { // 等会查询到 + o.setPid(null); + o.setName(null); + o.setIcon(null); + o.setBannerUrl(null); + o.setSort(null); + o.setDescription(null); + o.setStatus(null); + o.setCreateTime(null); + }); + categoryMapper.insert(dbCategory); + // 测试 pid 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setPid(null))); + // 测试 name 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName(null))); + // 测试 icon 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setIcon(null))); + // 测试 bannerUrl 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setBannerUrl(null))); + // 测试 sort 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setSort(null))); + // 测试 description 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setDescription(null))); + // 测试 status 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(null))); + // 测试 createTime 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(null))); + // 准备参数 + CategoryPageReqVO reqVO = new CategoryPageReqVO(); + reqVO.setName(null); + reqVO.setStatus(null); + reqVO.setBeginCreateTime(null); + reqVO.setEndCreateTime(null); + + // 调用 + PageResult<CategoryDO> pageResult = categoryService.getCategoryPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbCategory, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetCategoryList() { + // mock 数据 + CategoryDO dbCategory = randomPojo(CategoryDO.class, o -> { // 等会查询到 + o.setPid(null); + o.setName(null); + o.setIcon(null); + o.setBannerUrl(null); + o.setSort(null); + o.setDescription(null); + o.setStatus(null); + o.setCreateTime(null); + }); + categoryMapper.insert(dbCategory); + // 测试 pid 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setPid(null))); + // 测试 name 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName(null))); + // 测试 icon 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setIcon(null))); + // 测试 bannerUrl 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setBannerUrl(null))); + // 测试 sort 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setSort(null))); + // 测试 description 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setDescription(null))); + // 测试 status 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(null))); + // 测试 createTime 不匹配 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(null))); + // 准备参数 + CategoryExportReqVO reqVO = new CategoryExportReqVO(); + reqVO.setName(null); + reqVO.setStatus(null); + reqVO.setBeginCreateTime(null); + reqVO.setEndCreateTime(null); + + // 调用 + List<CategoryDO> list = categoryService.getCategoryList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbCategory, list.get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql new file mode 100644 index 000000000..7c66b9074 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql @@ -0,0 +1 @@ +DELETE FROM "product_category"; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql new file mode 100644 index 000000000..6400c8f0b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -0,0 +1,17 @@ +CREATE TABLE IF NOT EXISTS "product_category" ( + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "pid" bigint(20) NOT NULL, + "name" varchar(255) NOT NULL, + "icon" varchar(100), + "banner_url" varchar(255) NOT NULL, + "sort" int(11) NOT NULL, + "description" varchar(1024) NOT NULL, + "status" tinyint(4) NOT NULL, + "creator" varchar(64) DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint(20) NOT NULL, + PRIMARY KEY ("id") +) COMMENT '商品分类'; \ No newline at end of file diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 73eba6068..b7eed1e50 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -47,16 +47,21 @@ <artifactId>yudao-module-market-biz</artifactId> <version>${revision}</version> </dependency> + <dependency> + <groupId>cn.iocoder.boot</groupId> + <artifactId>yudao-module-product-biz</artifactId> + <version>${revision}</version> + </dependency> <!-- 默认引入 yudao-module-bpm-biz-flowable 实现,可以替换为 yudao-module-bpm-biz-activiti 实现--> <dependency> <groupId>cn.iocoder.boot</groupId> <artifactId>yudao-module-bpm-biz-flowable</artifactId> <version>${revision}</version> </dependency> -<!-- <dependency>--> -<!-- <groupId>cn.iocoder.boot</groupId>--> -<!-- <artifactId>yudao-module-bpm-biz-activiti</artifactId>--> -<!-- <version>${revision}</version>--> + <!-- <dependency>--> + <!-- <groupId>cn.iocoder.boot</groupId>--> + <!-- <artifactId>yudao-module-bpm-biz-activiti</artifactId>--> + <!-- <version>${revision}</version>--> <!-- </dependency>--> <!-- spring boot 配置所需依赖 --> diff --git a/yudao-ui-admin/src/api/mall/product/category.js b/yudao-ui-admin/src/api/mall/product/category.js new file mode 100644 index 000000000..33fde73cd --- /dev/null +++ b/yudao-ui-admin/src/api/mall/product/category.js @@ -0,0 +1,54 @@ +import request from '@/utils/request' + +// 创建商品分类 +export function createCategory(data) { + return request({ + url: '/product/category/create', + method: 'post', + data: data + }) +} + +// 更新商品分类 +export function updateCategory(data) { + return request({ + url: '/product/category/update', + method: 'put', + data: data + }) +} + +// 删除商品分类 +export function deleteCategory(id) { + return request({ + url: '/product/category/delete?id=' + id, + method: 'delete' + }) +} + +// 获得商品分类 +export function getCategory(id) { + return request({ + url: '/product/category/get?id=' + id, + method: 'get' + }) +} + +// 获得商品分类分页 +export function getCategoryPage(query) { + return request({ + url: '/product/category/page', + method: 'get', + params: query + }) +} + +// 导出商品分类 Excel +export function exportCategoryExcel(query) { + return request({ + url: '/product/category/export-excel', + method: 'get', + params: query, + responseType: 'blob' + }) +} diff --git a/yudao-ui-admin/src/views/mall/product/category/index.vue b/yudao-ui-admin/src/views/mall/product/category/index.vue new file mode 100644 index 000000000..57273c146 --- /dev/null +++ b/yudao-ui-admin/src/views/mall/product/category/index.vue @@ -0,0 +1,281 @@ +<template> + <div class="app-container"> + + <!-- 搜索工作栏 --> + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> + <el-form-item label="分类名称" prop="name"> + <el-input v-model="queryParams.name" placeholder="请输入分类名称" clearable @keyup.enter.native="handleQuery"/> + </el-form-item> + <el-form-item label="开启状态" prop="status"> + <el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable size="small"> + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)" + :key="dict.value" :label="dict.label" :value="dict.value"/> + </el-select> + </el-form-item> + <el-form-item label="创建时间"> + <el-date-picker v-model="dateRangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd" + type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> + <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> + </el-form-item> + </el-form> + + <!-- 操作工具栏 --> + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" + v-hasPermi="['product:category:create']">新增 + </el-button> + </el-col> + <el-col :span="1.5"> + <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" + :loading="exportLoading" + v-hasPermi="['product:category:export']">导出 + </el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <!-- 列表 --> + <el-table v-loading="loading" :data="list"> + <el-table-column label="分类编号" align="center" prop="id"/> + <el-table-column label="父分类编号" align="center" prop="pid"/> + <el-table-column label="分类名称" align="center" prop="name"/> + <el-table-column label="分类图标" align="center" prop="icon"/> + <el-table-column label="分类图片" align="center" prop="bannerUrl"/> + <el-table-column label="分类排序" align="center" prop="sort"/> + <el-table-column label="分类描述" align="center" prop="description"/> + <el-table-column label="开启状态" align="center" prop="status"> + <template slot-scope="scope"> + <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> + </template> + </el-table-column> + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" + v-hasPermi="['product:category:update']">修改 + </el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" + v-hasPermi="['product:category:delete']">删除 + </el-button> + </template> + </el-table-column> + </el-table> + <!-- 分页组件 --> + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" + @pagination="getList"/> + + <!-- 对话框(添加 / 修改) --> + <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="父分类编号" prop="pid"> + <el-input v-model="form.pid" placeholder="请输入父分类编号"/> + </el-form-item> + <el-form-item label="分类名称" prop="name"> + <el-input v-model="form.name" placeholder="请输入分类名称"/> + </el-form-item> + <el-form-item label="分类图标" prop="icon"> + <el-input v-model="form.icon" placeholder="请输入分类图标"/> + </el-form-item> + <el-form-item label="分类图片" prop="bannerUrl"> + <el-input v-model="form.bannerUrl" placeholder="请输入分类图片"/> + </el-form-item> + <el-form-item label="分类排序" prop="sort"> + <el-input v-model="form.sort" placeholder="请输入分类排序"/> + </el-form-item> + <el-form-item label="分类描述"> + <editor v-model="form.description" :min-height="192"/> + </el-form-item> + <el-form-item label="开启状态" prop="status"> + <el-radio-group v-model="form.status"> + <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)" + :key="dict.value" :label="parseInt(dict.value)">{{ dict.label }} + </el-radio> + </el-radio-group> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">确 定</el-button> + <el-button @click="cancel">取 消</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { + createCategory, + deleteCategory, + exportCategoryExcel, + getCategory, + getCategoryPage, + updateCategory +} from "@/api/mall/product/category"; +import Editor from '@/components/Editor'; + +export default { + name: "Category", + components: { + Editor, + }, + data() { + return { + // 遮罩层 + loading: true, + // 导出遮罩层 + exportLoading: false, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 商品分类列表 + list: [], + // 弹出层标题 + title: "", + // 是否显示弹出层 + open: false, + dateRangeCreateTime: [], + // 查询参数 + queryParams: { + pageNo: 1, + pageSize: 10, + name: null, + status: null, + }, + // 表单参数 + form: {}, + // 表单校验 + rules: { + pid: [{required: true, message: "父分类编号不能为空", trigger: "blur"}], + name: [{required: true, message: "分类名称不能为空", trigger: "blur"}], + bannerUrl: [{required: true, message: "分类图片不能为空", trigger: "blur"}], + sort: [{required: true, message: "分类排序不能为空", trigger: "blur"}], + description: [{required: true, message: "分类描述不能为空", trigger: "blur"}], + status: [{required: true, message: "开启状态不能为空", trigger: "blur"}], + } + }; + }, + created() { + this.getList(); + }, + methods: { + /** 查询列表 */ + getList() { + this.loading = true; + // 处理查询参数 + let params = {...this.queryParams}; + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); + // 执行查询 + getCategoryPage(params).then(response => { + this.list = response.data.list; + this.total = response.data.total; + this.loading = false; + }); + }, + /** 取消按钮 */ + cancel() { + this.open = false; + this.reset(); + }, + /** 表单重置 */ + reset() { + this.form = { + id: undefined, + pid: undefined, + name: undefined, + icon: undefined, + bannerUrl: undefined, + sort: undefined, + description: undefined, + status: undefined, + }; + this.resetForm("form"); + }, + /** 搜索按钮操作 */ + handleQuery() { + this.queryParams.pageNo = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery() { + this.dateRangeCreateTime = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 新增按钮操作 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "添加商品分类"; + }, + /** 修改按钮操作 */ + handleUpdate(row) { + this.reset(); + const id = row.id; + getCategory(id).then(response => { + this.form = response.data; + this.open = true; + this.title = "修改商品分类"; + }); + }, + /** 提交按钮 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (!valid) { + return; + } + // 修改的提交 + if (this.form.id != null) { + updateCategory(this.form).then(response => { + this.$modal.msgSuccess("修改成功"); + this.open = false; + this.getList(); + }); + return; + } + // 添加的提交 + createCategory(this.form).then(response => { + this.$modal.msgSuccess("新增成功"); + this.open = false; + this.getList(); + }); + }); + }, + /** 删除按钮操作 */ + handleDelete(row) { + const id = row.id; + this.$modal.confirm('是否确认删除商品分类编号为"' + id + '"的数据项?').then(function () { + return deleteCategory(id); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => { + }); + }, + /** 导出按钮操作 */ + handleExport() { + // 处理查询参数 + let params = {...this.queryParams}; + params.pageNo = undefined; + params.pageSize = undefined; + this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); + // 执行导出 + this.$modal.confirm('是否确认导出所有商品分类数据项?').then(() => { + this.exportLoading = true; + return exportCategoryExcel(params); + }).then(response => { + this.$download.excel(response, '${table.classComment}.xls'); + this.exportLoading = false; + }).catch(() => { + }); + } + } +}; +</script> From d3edaec2b1d7c54bc5e03450431fb68983ec6368 Mon Sep 17 00:00:00 2001 From: JeromeSoar <jeromesoar@mail.com> Date: Sun, 24 Apr 2022 17:01:10 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=95=86=E5=93=81=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E7=BB=B4=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mall.sql | 6 +- .../admin/category/CategoryController.java | 48 +++++++------ .../admin/category/vo/CategoryBaseVO.java | 16 ++--- .../service/category/CategoryService.java | 19 +++-- .../service/category/CategoryServiceImpl.java | 26 ++++--- .../src/api/mall/product/category.js | 9 +++ .../src/views/mall/product/category/index.vue | 71 +++++++++++++++---- 7 files changed, 137 insertions(+), 58 deletions(-) diff --git a/sql/mall.sql b/sql/mall.sql index 390044e06..825d43e36 100644 --- a/sql/mall.sql +++ b/sql/mall.sql @@ -26,10 +26,10 @@ CREATE TABLE `product_category` `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', `pid` bigint NOT NULL COMMENT '父分类编号', `name` varchar(255) NOT NULL COMMENT '分类名称', - `icon` varchar(100) DEFAULT '#' COMMENT '分类图标', + `icon` varchar(100) NOT NULL DEFAULT '#' COMMENT '分类图标', `banner_url` varchar(255) NOT NULL COMMENT '分类图片', - `sort` int NOT NULL DEFAULT '0' COMMENT '分类排序', - `description` varchar(1024) NOT NULL COMMENT '分类描述', + `sort` int DEFAULT '0' COMMENT '分类排序', + `description` varchar(1024) DEFAULT NULL COMMENT '分类描述', `status` tinyint NOT NULL COMMENT '开启状态', `creator` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java index 346b3177a..ed22def1d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java @@ -1,30 +1,29 @@ package cn.iocoder.yudao.module.product.controller.admin.category; -import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import org.springframework.validation.annotation.Validated; -import org.springframework.security.access.prepost.PreAuthorize; -import io.swagger.annotations.*; - -import javax.validation.constraints.*; -import javax.validation.*; -import javax.servlet.http.*; -import java.util.*; -import java.io.IOException; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; - import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; - import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; import cn.iocoder.yudao.module.product.service.category.CategoryService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @Api(tags = "管理后台 - 商品分类") @RestController @@ -68,15 +67,22 @@ public class CategoryController { return success(CategoryConvert.INSTANCE.convert(category)); } - @GetMapping("/list") + @GetMapping("/listByIds") @ApiOperation("获得商品分类列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) @PreAuthorize("@ss.hasPermission('product:category:query')") public CommonResult<List<CategoryRespVO>> getCategoryList(@RequestParam("ids") Collection<Long> ids) { List<CategoryDO> list = categoryService.getCategoryList(ids); return success(CategoryConvert.INSTANCE.convertList(list)); } + @GetMapping("/listByQuery") + @ApiOperation("获得商品分类列表") + @PreAuthorize("@ss.hasPermission('product:category:query')") + public CommonResult<List<CategoryRespVO>> listByQuery() { + List<CategoryDO> list = categoryService.listByQuery(); + return success(CategoryConvert.INSTANCE.convertList(list)); + } + @GetMapping("/page") @ApiOperation("获得商品分类分页") @PreAuthorize("@ss.hasPermission('product:category:query')") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java index 82f2ba09d..d4c2ebb8b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java @@ -1,9 +1,10 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; /** * 商品分类 Base VO,提供给添加、修改、详细的子 VO 使用 @@ -17,22 +18,21 @@ public class CategoryBaseVO { private Long pid; @ApiModelProperty(value = "分类名称", required = true, example = "办公文具") - @NotNull(message = "分类名称不能为空") + @NotBlank(message = "分类名称不能为空") private String name; @ApiModelProperty(value = "分类图标") + @NotBlank(message = "分类图标不能为空") private String icon; @ApiModelProperty(value = "分类图片", required = true) - @NotNull(message = "分类图片不能为空") + @NotBlank(message = "分类图片不能为空") private String bannerUrl; @ApiModelProperty(value = "分类排序", required = true, example = "1") - @NotNull(message = "分类排序不能为空") private Integer sort; @ApiModelProperty(value = "分类描述", required = true, example = "描述") - @NotNull(message = "分类描述不能为空") private String description; @ApiModelProperty(value = "开启状态", required = true, example = "0") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java index ff5f520fa..89ac934fb 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java @@ -1,10 +1,15 @@ package cn.iocoder.yudao.module.product.service.category; -import java.util.*; -import javax.validation.*; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; /** * 商品分类 Service 接口 @@ -67,4 +72,10 @@ public interface CategoryService { */ List<CategoryDO> getCategoryList(CategoryExportReqVO exportReqVO); + /** + * 获得商品分类列表 + * + * @return 商品分类列表 + */ + List<CategoryDO> listByQuery(); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java index 873bad297..1465892f6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java @@ -1,19 +1,22 @@ package cn.iocoder.yudao.module.product.service.category; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; +import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper; import org.springframework.stereotype.Service; -import javax.annotation.Resource; import org.springframework.validation.annotation.Validated; -import java.util.*; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; -import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper; +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; /** * 商品分类 Service 实现类 @@ -79,4 +82,9 @@ public class CategoryServiceImpl implements CategoryService { return categoryMapper.selectList(exportReqVO); } + @Override + public List<CategoryDO> listByQuery() { + return categoryMapper.selectList(); + } + } diff --git a/yudao-ui-admin/src/api/mall/product/category.js b/yudao-ui-admin/src/api/mall/product/category.js index 33fde73cd..bd825034d 100644 --- a/yudao-ui-admin/src/api/mall/product/category.js +++ b/yudao-ui-admin/src/api/mall/product/category.js @@ -34,6 +34,15 @@ export function getCategory(id) { }) } +// 获得商品分类 +export function listCategory(query) { + return request({ + url: '/product/category/listByQuery', + method: 'get', + params: query + }) +} + // 获得商品分类分页 export function getCategoryPage(query) { return request({ diff --git a/yudao-ui-admin/src/views/mall/product/category/index.vue b/yudao-ui-admin/src/views/mall/product/category/index.vue index 57273c146..26cfcdf94 100644 --- a/yudao-ui-admin/src/views/mall/product/category/index.vue +++ b/yudao-ui-admin/src/views/mall/product/category/index.vue @@ -40,13 +40,18 @@ <!-- 列表 --> <el-table v-loading="loading" :data="list"> - <el-table-column label="分类编号" align="center" prop="id"/> - <el-table-column label="父分类编号" align="center" prop="pid"/> <el-table-column label="分类名称" align="center" prop="name"/> - <el-table-column label="分类图标" align="center" prop="icon"/> - <el-table-column label="分类图片" align="center" prop="bannerUrl"/> + <el-table-column label="分类图标" align="center" prop="icon"> + <template slot-scope="scope"> + <svg-icon :icon-class="scope.row.icon" /> + </template> + </el-table-column> + <el-table-column label="分类图片" align="center" prop="bannerUrl"> + <template slot-scope="scope"> + <img v-if="scope.row.bannerUrl" :src="scope.row.bannerUrl" alt="分类图片"/> + </template> + </el-table-column> <el-table-column label="分类排序" align="center" prop="sort"/> - <el-table-column label="分类描述" align="center" prop="description"/> <el-table-column label="开启状态" align="center" prop="status"> <template slot-scope="scope"> <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> @@ -75,20 +80,28 @@ <!-- 对话框(添加 / 修改) --> <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> <el-form ref="form" :model="form" :rules="rules" label-width="80px"> - <el-form-item label="父分类编号" prop="pid"> - <el-input v-model="form.pid" placeholder="请输入父分类编号"/> + <el-form-item label="上级分类" prop="pid"> + <Treeselect v-model="form.pid" :options="parentCategoryOptions" :normalizer="normalizer" :show-count="true" + placeholder="上级分类"/> </el-form-item> <el-form-item label="分类名称" prop="name"> <el-input v-model="form.name" placeholder="请输入分类名称"/> </el-form-item> <el-form-item label="分类图标" prop="icon"> - <el-input v-model="form.icon" placeholder="请输入分类图标"/> + <el-popover placement="bottom-start" width="460" trigger="click" @show="$refs['iconSelect'].reset()"> + <IconSelect ref="iconSelect" @selected="iconSelected"/> + <el-input slot="reference" v-model="form.icon" placeholder="点击选择分类图标" readonly> + <svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" + style="height: 32px;width: 16px;"/> + <i v-else slot="prefix" class="el-icon-search el-input__icon"/> + </el-input> + </el-popover> </el-form-item> <el-form-item label="分类图片" prop="bannerUrl"> <el-input v-model="form.bannerUrl" placeholder="请输入分类图片"/> </el-form-item> <el-form-item label="分类排序" prop="sort"> - <el-input v-model="form.sort" placeholder="请输入分类排序"/> + <el-input-number v-model="form.sort" controls-position="right" :min="0" /> </el-form-item> <el-form-item label="分类描述"> <editor v-model="form.description" :min-height="192"/> @@ -116,14 +129,19 @@ import { exportCategoryExcel, getCategory, getCategoryPage, + listCategory, updateCategory } from "@/api/mall/product/category"; import Editor from '@/components/Editor'; +import Treeselect from "@riophae/vue-treeselect"; +import "@riophae/vue-treeselect/dist/vue-treeselect.css"; +import IconSelect from "@/components/IconSelect"; +import ImageUpload from '@/components/ImageUpload'; export default { name: "Category", components: { - Editor, + Editor, Treeselect, IconSelect, ImageUpload }, data() { return { @@ -137,6 +155,8 @@ export default { total: 0, // 商品分类列表 list: [], + // 商品分类树选项 + parentCategoryOptions: [], // 弹出层标题 title: "", // 是否显示弹出层 @@ -153,11 +173,10 @@ export default { form: {}, // 表单校验 rules: { - pid: [{required: true, message: "父分类编号不能为空", trigger: "blur"}], + pid: [{required: true, message: "请选择上级分类", trigger: "blur"}], name: [{required: true, message: "分类名称不能为空", trigger: "blur"}], + icon: [{required: true, message: "分类图标不能为空", trigger: "blur"}], bannerUrl: [{required: true, message: "分类图片不能为空", trigger: "blur"}], - sort: [{required: true, message: "分类排序不能为空", trigger: "blur"}], - description: [{required: true, message: "分类描述不能为空", trigger: "blur"}], status: [{required: true, message: "开启状态不能为空", trigger: "blur"}], } }; @@ -179,6 +198,30 @@ export default { this.loading = false; }); }, + // 选择图标 + iconSelected(name) { + this.form.icon = name; + }, + /** 转换菜单数据结构 */ + normalizer(node) { + if (node.children && !node.children.length) { + delete node.children; + } + return { + id: node.id, + label: node.name, + children: node.children + }; + }, + /** 查询分类下拉树结构 */ + getTreeselect() { + listCategory().then(response => { + this.parentCategoryOptions = []; + const menu = {id: 0, name: '主分类', children: []}; + menu.children = this.handleTree(response.data, "id", "pid"); + this.parentCategoryOptions.push(menu); + }); + }, /** 取消按钮 */ cancel() { this.open = false; @@ -212,12 +255,14 @@ export default { /** 新增按钮操作 */ handleAdd() { this.reset(); + this.getTreeselect(); this.open = true; this.title = "添加商品分类"; }, /** 修改按钮操作 */ handleUpdate(row) { this.reset(); + this.getTreeselect(); const id = row.id; getCategory(id).then(response => { this.form = response.data; From e4ca2e25f9f518e366b4266cff9553bb49bea1c4 Mon Sep 17 00:00:00 2001 From: JeromeSoar <jeromesoar@mail.com> Date: Sun, 24 Apr 2022 17:37:52 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=A0=91=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/category/CategoryController.java | 6 ++-- .../category/vo/CategoryTreeListReqVO.java | 29 ++++++++++++++++ .../service/category/CategoryService.java | 8 ++--- .../service/category/CategoryServiceImpl.java | 9 ++--- .../src/views/mall/product/category/index.vue | 34 +++++++++++-------- 5 files changed, 58 insertions(+), 28 deletions(-) create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryTreeListReqVO.java diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java index ed22def1d..9e5614a87 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java @@ -20,6 +20,7 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; import java.util.Collection; +import java.util.Comparator; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -78,8 +79,9 @@ public class CategoryController { @GetMapping("/listByQuery") @ApiOperation("获得商品分类列表") @PreAuthorize("@ss.hasPermission('product:category:query')") - public CommonResult<List<CategoryRespVO>> listByQuery() { - List<CategoryDO> list = categoryService.listByQuery(); + public CommonResult<List<CategoryRespVO>> listByQuery(@Valid CategoryTreeListReqVO treeListReqVO) { + List<CategoryDO> list = categoryService.getCategoryTreeList(treeListReqVO); + list.sort(Comparator.comparing(CategoryDO::getSort)); return success(CategoryConvert.INSTANCE.convertList(list)); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryTreeListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryTreeListReqVO.java new file mode 100644 index 000000000..12256efd3 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryTreeListReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Data +@ApiModel(value = "管理后台 - 商品分类列表查询 Request VO", description = "参数和 CategoryPageReqVO 是一致的") +public class CategoryTreeListReqVO extends CategoryExportReqVO { + + @ApiModelProperty(value = "分类名称", example = "办公文具") + private String name; + + @ApiModelProperty(value = "开启状态", example = "0") + private Integer status; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java index 89ac934fb..b29b3418f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java @@ -1,10 +1,7 @@ package cn.iocoder.yudao.module.product.service.category; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; import javax.validation.Valid; @@ -75,7 +72,8 @@ public interface CategoryService { /** * 获得商品分类列表 * + * @param treeListReqVO 查询条件 * @return 商品分类列表 */ - List<CategoryDO> listByQuery(); + List<CategoryDO> getCategoryTreeList(CategoryTreeListReqVO treeListReqVO); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java index 1465892f6..b84ac5b9a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java @@ -1,10 +1,7 @@ package cn.iocoder.yudao.module.product.service.category; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper; @@ -83,8 +80,8 @@ public class CategoryServiceImpl implements CategoryService { } @Override - public List<CategoryDO> listByQuery() { - return categoryMapper.selectList(); + public List<CategoryDO> getCategoryTreeList(CategoryTreeListReqVO treeListReqVO) { + return categoryMapper.selectList(treeListReqVO); } } diff --git a/yudao-ui-admin/src/views/mall/product/category/index.vue b/yudao-ui-admin/src/views/mall/product/category/index.vue index 26cfcdf94..cfef21c0f 100644 --- a/yudao-ui-admin/src/views/mall/product/category/index.vue +++ b/yudao-ui-admin/src/views/mall/product/category/index.vue @@ -12,10 +12,6 @@ :key="dict.value" :label="dict.label" :value="dict.value"/> </el-select> </el-form-item> - <el-form-item label="创建时间"> - <el-date-picker v-model="dateRangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd" - type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/> - </el-form-item> <el-form-item> <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> @@ -29,6 +25,9 @@ v-hasPermi="['product:category:create']">新增 </el-button> </el-col> + <el-col :span="1.5"> + <el-button type="info" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">展开/折叠</el-button> + </el-col> <el-col :span="1.5"> <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading" @@ -39,7 +38,8 @@ </el-row> <!-- 列表 --> - <el-table v-loading="loading" :data="list"> + <el-table v-if="refreshTable" v-loading="loading" :data="list" row-key="id" :default-expand-all="isExpandAll" + :tree-props="{children: 'children', hasChildren: 'hasChildren'}"> <el-table-column label="分类名称" align="center" prop="name"/> <el-table-column label="分类图标" align="center" prop="icon"> <template slot-scope="scope"> @@ -73,9 +73,6 @@ </template> </el-table-column> </el-table> - <!-- 分页组件 --> - <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" - @pagination="getList"/> <!-- 对话框(添加 / 修改) --> <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> @@ -161,7 +158,10 @@ export default { title: "", // 是否显示弹出层 open: false, - dateRangeCreateTime: [], + // 是否展开,默认全部折叠 + isExpandAll: false, + // 重新渲染表格状态 + refreshTable: true, // 查询参数 queryParams: { pageNo: 1, @@ -190,11 +190,9 @@ export default { this.loading = true; // 处理查询参数 let params = {...this.queryParams}; - this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); // 执行查询 - getCategoryPage(params).then(response => { - this.list = response.data.list; - this.total = response.data.total; + listCategory(params).then(response => { + this.list = this.handleTree(response.data, "id", "pid"); this.loading = false; }); }, @@ -248,10 +246,17 @@ export default { }, /** 重置按钮操作 */ resetQuery() { - this.dateRangeCreateTime = []; this.resetForm("queryForm"); this.handleQuery(); }, + /** 展开/折叠操作 */ + toggleExpandAll() { + this.refreshTable = false; + this.isExpandAll = !this.isExpandAll; + this.$nextTick(() => { + this.refreshTable = true; + }); + }, /** 新增按钮操作 */ handleAdd() { this.reset(); @@ -310,7 +315,6 @@ export default { let params = {...this.queryParams}; params.pageNo = undefined; params.pageSize = undefined; - this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime'); // 执行导出 this.$modal.confirm('是否确认导出所有商品分类数据项?').then(() => { this.exportLoading = true; From e3589eae11e00ab530d0ea8eb6bd1fe8d8b367f9 Mon Sep 17 00:00:00 2001 From: JeromeSoar <jeromesoar@mail.com> Date: Sun, 24 Apr 2022 17:55:16 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E7=AE=80=E5=8D=95=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/controller/admin/file/FileController.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java index e3d810dec..3dc49738a 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.file; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.IoUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -23,6 +24,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import java.util.Date; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -47,6 +49,16 @@ public class FileController { return success(fileService.createFile(path, IoUtil.readBytes(file.getInputStream()))); } + @PostMapping("/simple-upload") + @ApiOperation("简单上传文件") + @ApiImplicitParams({ + @ApiImplicitParam(name = "file", value = "文件附件", required = true, dataTypeClass = MultipartFile.class), + }) + public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file) throws Exception { + String path = DateUtil.format(new Date(), "yyyy/MM/dd/") + file.getName(); + return success(fileService.createFile(path, IoUtil.readBytes(file.getInputStream()))); + } + @DeleteMapping("/delete") @ApiOperation("删除文件") @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) From df23750203ab08cb763755448e24b2a506b14ef9 Mon Sep 17 00:00:00 2001 From: JeromeSoar <jeromesoar@mail.com> Date: Sun, 24 Apr 2022 18:02:25 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/infra/controller/admin/file/FileController.java | 2 +- yudao-ui-admin/src/components/ImageUpload/index.vue | 2 +- yudao-ui-admin/src/views/mall/product/category/index.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java index 3dc49738a..3ec24c9b1 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java @@ -55,7 +55,7 @@ public class FileController { @ApiImplicitParam(name = "file", value = "文件附件", required = true, dataTypeClass = MultipartFile.class), }) public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file) throws Exception { - String path = DateUtil.format(new Date(), "yyyy/MM/dd/") + file.getName(); + String path = DateUtil.format(new Date(), "yyyy/MM/dd/") + file.getOriginalFilename(); return success(fileService.createFile(path, IoUtil.readBytes(file.getInputStream()))); } diff --git a/yudao-ui-admin/src/components/ImageUpload/index.vue b/yudao-ui-admin/src/components/ImageUpload/index.vue index 170c1bd08..3462f250d 100644 --- a/yudao-ui-admin/src/components/ImageUpload/index.vue +++ b/yudao-ui-admin/src/components/ImageUpload/index.vue @@ -77,7 +77,7 @@ export default { dialogVisible: false, hideUpload: false, baseUrl: process.env.VUE_APP_BASE_API, - uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址 + uploadImgUrl: process.env.VUE_APP_BASE_API + "/admin-api/infra/file/simple-upload", // 上传的图片服务器地址 headers: { Authorization: "Bearer " + getToken(), }, diff --git a/yudao-ui-admin/src/views/mall/product/category/index.vue b/yudao-ui-admin/src/views/mall/product/category/index.vue index cfef21c0f..751ad9c52 100644 --- a/yudao-ui-admin/src/views/mall/product/category/index.vue +++ b/yudao-ui-admin/src/views/mall/product/category/index.vue @@ -95,7 +95,7 @@ </el-popover> </el-form-item> <el-form-item label="分类图片" prop="bannerUrl"> - <el-input v-model="form.bannerUrl" placeholder="请输入分类图片"/> + <ImageUpload v-model="form.bannerUrl" /> </el-form-item> <el-form-item label="分类排序" prop="sort"> <el-input-number v-model="form.sort" controls-position="right" :min="0" /> From 145238ea967afa381086fd354982fec7defb035e Mon Sep 17 00:00:00 2001 From: JeromeSoar <jeromesoar@mail.com> Date: Sun, 24 Apr 2022 18:05:54 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/infra/controller/admin/file/FileController.java | 3 ++- yudao-ui-admin/src/components/ImageUpload/index.vue | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java index 3ec24c9b1..f53b45ac8 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java @@ -56,7 +56,8 @@ public class FileController { }) public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file) throws Exception { String path = DateUtil.format(new Date(), "yyyy/MM/dd/") + file.getOriginalFilename(); - return success(fileService.createFile(path, IoUtil.readBytes(file.getInputStream()))); + String file1 = fileService.createFile(path, IoUtil.readBytes(file.getInputStream())); + return success(file1); } @DeleteMapping("/delete") diff --git a/yudao-ui-admin/src/components/ImageUpload/index.vue b/yudao-ui-admin/src/components/ImageUpload/index.vue index 3462f250d..b736b7240 100644 --- a/yudao-ui-admin/src/components/ImageUpload/index.vue +++ b/yudao-ui-admin/src/components/ImageUpload/index.vue @@ -127,7 +127,7 @@ export default { }, // 上传成功回调 handleUploadSuccess(res) { - this.uploadList.push({ name: res.fileName, url: res.fileName }); + this.uploadList.push({ name: res.data, url: res.data }); if (this.uploadList.length === this.number) { this.fileList = this.fileList.concat(this.uploadList); this.uploadList = [];