demo测试模块类初始化v2

ccongli-dev-0821
LI-CCONG\李聪聪 1 year ago
parent 3f7b71623b
commit 030d992779

@ -0,0 +1,28 @@
<?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">
<parent>
<artifactId>yunxi-module-demo</artifactId>
<groupId>com.yunxi.scm</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yunxi-module-demo-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
demo 模块 API暴露给其它模块调用
</description>
<!-- 新增 yudao-common 依赖 -->
<dependencies>
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-common</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,18 @@
package com.yunxi.scm.module.demo.enums;
/**
* System
*
* @author
*/
public interface DictTypeConstants {
String USER_TYPE = "user_type"; // 用户类型
String COMMON_STATUS = "common_status"; // 系统状态
String MATERIAL_STATUS = "material_status"; // 物料状态
// ========== SYSTEM 模块 ==========
String TRADE_ORDER_TYPE = "trade_order_type"; // 订单交易类型
}

@ -0,0 +1,9 @@
// TODO 待办:请将下面的错误码复制到 yunxi-module-demo-api 模块的 ErrorCodeConstants 类中。注意请给“TODO 补充编号”设置一个错误码编号!!!
// ========== 物料管理 TODO 补充编号 ==========
package com.yunxi.scm.module.demo.enums;
import com.yunxi.scm.framework.common.exception.ErrorCode;
public interface ErrorCodeConstants {
ErrorCode MATERIAL_NOT_EXISTS = new ErrorCode(2023091001, "物料管理不存在");
}

@ -0,0 +1,72 @@
<?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">
<parent>
<artifactId>yunxi-module-demo</artifactId>
<groupId>com.yunxi.scm</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>yunxi-module-demo-biz</artifactId>
<name>${project.artifactId}</name>
<description>
demo 模块,主要实现 XXX、YYY、ZZZ 等功能。
</description>
<!-- 新增依赖,这里引入的都是比较常用的业务组件、技术组件 -->
<dependencies>
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-module-demo-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-spring-boot-starter-biz-operatelog</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-spring-boot-starter-web</artifactId>
</dependency>
<!-- 功能权限 相关 -->
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-spring-boot-starter-security</artifactId>
</dependency>
<!-- 数据权限 相关 -->
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-spring-boot-starter-biz-data-permission</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-spring-boot-starter-test</artifactId>
</dependency>
<!-- Excel 相关 -->
<dependency>
<groupId>com.yunxi.scm</groupId>
<artifactId>yunxi-spring-boot-starter-excel</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,119 @@
package com.yunxi.scm.module.demo.controller.admin;
import com.yunxi.scm.framework.common.pojo.CommonResult;
import com.yunxi.scm.framework.excel.core.util.ExcelUtils;
import com.yunxi.scm.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yunxi.scm.framework.operatelog.core.annotations.OperateLog;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialExportTestVO;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialImportTestVO;
import com.yunxi.scm.module.demo.convert.material.MaterialXConvert;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialXDO;
import com.yunxi.scm.module.demo.dal.mysql.material.MaterialXMapper;
import com.yunxi.scm.module.demo.enums.material.CategoryEnum;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.yunxi.scm.framework.common.pojo.CommonResult.success;
import static com.yunxi.scm.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static com.yunxi.scm.framework.operatelog.core.enums.OperateTypeEnum.IMPORT;
@Tag(name = "管理后台 - Test")
@RestController
@RequestMapping("/demo/test")
@Validated
public class DemoTestController {
@GetMapping("/get")
@Operation(summary = "获取 test 信息")
@PermitAll // 无需认证即可访问
public CommonResult<String> get() {
return success("无需认证即可访问的后台接口");
}
@GetMapping("/test_export")
@Operation(summary = "测试导出和字典转化")
@PermitAll
@OperateLog(type = EXPORT)
public void testExport(HttpServletResponse response) throws IOException {
MaterialXDO xdo1 = new MaterialXDO(1L,"80inu5yxl3",Arrays.asList("1","2"));
MaterialXDO xdo2 = new MaterialXDO(2L,"Q2ZY1I9cCBf0YKvDUlzCbw==",Arrays.asList("1","3"));
List<MaterialXDO> xdos = new ArrayList<>();
xdos.add(xdo1);
xdos.add(xdo2);
List<MaterialExportTestVO> datas = MaterialXConvert.INSTANCE.convertList03(xdos);
ExcelUtils.write(response, "测试导出.xls", "数据", MaterialExportTestVO.class, datas);
}
@PostMapping("/test_import")
@Operation(summary = "测试导入和转化为字典")
@PermitAll
@OperateLog(type = IMPORT)
@Parameters({
@Parameter(name = "file", description = "Excel 文件", required = true),
@Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
})
public CommonResult<List<MaterialImportTestVO>> testImport(@RequestParam("file") MultipartFile file,
@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws IOException {
List<MaterialImportTestVO> list = ExcelUtils.read(file, MaterialImportTestVO.class);
return success(list);
}
@GetMapping("/get-import-template")
@PermitAll
@Operation(summary = "获得导入模板")
public void importTemplate(HttpServletResponse response) throws IOException {
List<String> values = Stream.of(CategoryEnum.COMMON.getCode(),CategoryEnum.KANJIA.getCode())
.map(String::valueOf).collect(Collectors.toList());
// 手动创建导出 demo
List<MaterialImportTestVO> list = Arrays.asList(
MaterialImportTestVO.builder().category(values).build()
);
// 输出
ExcelUtils.write(response, "导入模板.xls", "物料标准模版", MaterialImportTestVO.class, list);
}
@Resource
MaterialXMapper materialXMapper;
@GetMapping("/test_encrypt")
@Operation(summary = "测试字段加密")
@PermitAll
public CommonResult<String> testEncrypt() {
MaterialXDO xdo1 = new MaterialXDO(1L,"80inu5yxl3",Arrays.asList("1","2"));
MaterialXDO xdo2 = new MaterialXDO(2L,"80inu5yxl3",Arrays.asList("1","3"));
List<MaterialXDO> xdos = new ArrayList<>();
xdos.add(xdo1);
xdos.add(xdo2);
materialXMapper.insertBatch(xdos);
return success("ok");
}
@GetMapping("/test_decrypt")
@Operation(summary = "测试字段解密")
@PermitAll
public CommonResult<MaterialExportTestVO> testDecrypt() {
LambdaQueryWrapperX<MaterialXDO> wrapperX = new LambdaQueryWrapperX<>();
wrapperX.eq(MaterialXDO::getId, 1);
MaterialXDO xdo = materialXMapper.selectOne(wrapperX);
return success(MaterialXConvert.INSTANCE.convert(xdo));
}
}

@ -0,0 +1,101 @@
package com.yunxi.scm.module.demo.controller.admin.material;
import com.yunxi.scm.framework.common.pojo.CommonResult;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.framework.datapermission.core.annotation.DataPermission;
import com.yunxi.scm.framework.excel.core.util.ExcelUtils;
import com.yunxi.scm.framework.operatelog.core.annotations.OperateLog;
import com.yunxi.scm.module.demo.controller.admin.material.vo.*;
import com.yunxi.scm.module.demo.convert.material.MaterialConvert;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialDO;
import com.yunxi.scm.module.demo.service.material.PMaterialService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
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 com.yunxi.scm.framework.common.pojo.CommonResult.success;
import static com.yunxi.scm.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@Tag(name = "管理后台 - 物料管理")
@RestController
@RequestMapping("/demo/material")
@Validated
public class PMaterialController {
@Resource
private PMaterialService materialService;
@PostMapping("/create")
@Operation(summary = "创建物料管理")
@PreAuthorize("@ss.hasPermission('demo:material:create')")
public CommonResult<Long> createMaterial(@Valid @RequestBody MaterialCreateReqVO createReqVO) {
return success(materialService.createMaterial(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新物料管理")
@PreAuthorize("@ss.hasPermission('demo:material:update')")
public CommonResult<Boolean> updateMaterial(@Valid @RequestBody MaterialUpdateReqVO updateReqVO) {
materialService.updateMaterial(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除物料管理")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('demo:material:delete')")
public CommonResult<Boolean> deleteMaterial(@RequestParam("id") Long id) {
materialService.deleteMaterial(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得物料管理")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('demo:material:query')")
public CommonResult<MaterialRespVO> getMaterial(@RequestParam("id") Long id) {
MaterialDO material = materialService.getMaterial(id);
return success(MaterialConvert.INSTANCE.convert(material));
}
@GetMapping("/list")
@Operation(summary = "获得物料管理列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('demo:material:query')")
public CommonResult<List<MaterialRespVO>> getMaterialList(@RequestParam("ids") Collection<Long> ids) {
List<MaterialDO> list = materialService.getMaterialList(ids);
return success(MaterialConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得物料管理分页")
@PreAuthorize("@ss.hasPermission('demo:material:query')")
@DataPermission // 数据权限功能,默认是开启的
public CommonResult<PageResult<MaterialRespVO>> getMaterialPage(@Valid MaterialPageReqVO pageVO) {
PageResult<MaterialDO> pageResult = materialService.getMaterialPage(pageVO);
return success(MaterialConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出物料管理 Excel")
@PreAuthorize("@ss.hasPermission('demo:material:export')")
@OperateLog(type = EXPORT)
public void exportMaterialExcel(@Valid MaterialExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<MaterialDO> list = materialService.getMaterialList(exportReqVO);
// 导出 Excel
List<MaterialExcelVO> datas = MaterialConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "物料管理.xls", "数据", MaterialExcelVO.class, datas);
}
}

@ -0,0 +1,48 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
/**
* Base VO VO 使
* VO Swagger
*/
@Data
public class MaterialBaseVO {
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@NotNull(message = "名称不能为空")
private String name;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
private Byte status;
@Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "类型不能为空")
private Byte type;
@Schema(description = "分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2")
@NotNull(message = "分类不能为空")
private List<String> categories;
@Schema(description = "图片", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
@NotNull(message = "图片不能为空")
private String imgurl;
@Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "库存数量不能为空")
private Integer stock;
@Schema(description = "单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "18.00")
@NotNull(message = "单价不能为空")
private BigDecimal price;
@Schema(description = "备注", example = "物料备注")
private String remark;
}

@ -0,0 +1,14 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 物料管理创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MaterialCreateReqVO extends MaterialBaseVO {
}

@ -0,0 +1,56 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.yunxi.scm.framework.excel.core.annotations.DictFormat;
import com.yunxi.scm.framework.excel.core.convert.DictConvert;
import com.yunxi.scm.framework.excel.core.convert.JsonConvert;
import com.yunxi.scm.module.demo.enums.DictTypeConstants;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
* Excel VO
*
* @author ccongli
*/
@Data
public class MaterialExcelVO {
@ExcelProperty("编号")
private Long id;
@ExcelProperty("名称")
private String name;
@ExcelProperty(value = "状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.MATERIAL_STATUS)
private Byte status;
@ExcelProperty(value = "类型", converter = DictConvert.class)
@DictFormat(DictTypeConstants.TRADE_ORDER_TYPE)
private Byte type;
@ExcelProperty(value = "分类", converter = JsonConvert.class)
private List<String> categories;
@ExcelProperty("图片")
private String imgurl;
@ExcelProperty("库存数量")
private Integer stock;
@ExcelProperty("单价")
private BigDecimal price;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,31 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.yunxi.scm.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 物料管理 Excel 导出 Request VO参数和 MaterialPageReqVO 是一致的")
@Data
public class MaterialExportReqVO {
@Schema(description = "名称", example = "李四")
private String name;
@Schema(description = "状态", example = "1")
private Byte status;
@Schema(description = "类型", example = "2")
private Byte type;
@Schema(description = "分类", example = "1")
private String category;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,21 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.yunxi.scm.framework.excel.core.annotations.DictFormat;
import com.yunxi.scm.framework.excel.core.convert.MutilDictConvert;
import com.yunxi.scm.module.demo.enums.DictTypeConstants;
import lombok.Data;
import java.util.List;
// 测试转换
@Data
public class MaterialExportTestVO {
@ExcelProperty(value = "密码")
private String password;
@ExcelProperty(value = "分类测试", converter = MutilDictConvert.class)
@DictFormat(DictTypeConstants.TRADE_ORDER_TYPE)
private List<String> category;
}

@ -0,0 +1,27 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.yunxi.scm.framework.excel.core.annotations.DictFormat;
import com.yunxi.scm.framework.excel.core.convert.MutilDictConvert;
import com.yunxi.scm.module.demo.enums.DictTypeConstants;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = false) // 设置 chain = false避免用户导入有问题
public class MaterialImportTestVO {
@ExcelProperty(value = "分类测试", converter = MutilDictConvert.class)
@DictFormat(DictTypeConstants.TRADE_ORDER_TYPE)
private List<String> category;
}

@ -0,0 +1,36 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import com.yunxi.scm.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.yunxi.scm.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 物料管理分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MaterialPageReqVO extends PageParam {
@Schema(description = "名称", example = "李四")
private String name;
@Schema(description = "状态", example = "1")
private Byte status;
@Schema(description = "类型", example = "2")
private Byte type;
@Schema(description = "分类", example = "2")
private String category;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,19 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 物料管理 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MaterialRespVO extends MaterialBaseVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14541")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

@ -0,0 +1,18 @@
package com.yunxi.scm.module.demo.controller.admin.material.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 物料管理更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MaterialUpdateReqVO extends MaterialBaseVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14541")
@NotNull(message = "ID不能为空")
private Long id;
}

@ -0,0 +1,27 @@
package com.yunxi.scm.module.demo.controller.app;
import com.yunxi.scm.framework.common.pojo.CommonResult;
import com.yunxi.scm.framework.security.core.annotations.PreAuthenticated;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static com.yunxi.scm.framework.common.pojo.CommonResult.success;
@Tag(name = "用户 App - Test")
@RestController
@RequestMapping("/demo/test")
@Validated
public class AppDemoTestController {
@GetMapping("/get")
@Operation(summary = "获取 test 信息")
@PreAuthenticated // 认证后可访问
public CommonResult<String> get() {
return success("需认证后才能访问的app接口");
}
}

@ -0,0 +1,37 @@
package com.yunxi.scm.module.demo.convert.material;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.module.demo.controller.admin.material.vo.*;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialDO;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialXDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* Convert
*
* @author ccongli
*/
@Mapper
public interface MaterialConvert {
MaterialConvert INSTANCE = Mappers.getMapper(MaterialConvert.class);
MaterialDO convert(MaterialCreateReqVO bean);
MaterialDO convert(MaterialUpdateReqVO bean);
MaterialRespVO convert(MaterialDO bean);
List<MaterialRespVO> convertList(List<MaterialDO> list);
PageResult<MaterialRespVO> convertPage(PageResult<MaterialDO> page);
List<MaterialExcelVO> convertList02(List<MaterialDO> list);
List<MaterialExportTestVO> convertList03(List<MaterialXDO> list);
}

@ -0,0 +1,24 @@
package com.yunxi.scm.module.demo.convert.material;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialExportTestVO;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialXDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* Convert
*
* @author ccongli
*/
@Mapper
public interface MaterialXConvert {
MaterialXConvert INSTANCE = Mappers.getMapper(MaterialXConvert.class);
MaterialExportTestVO convert(MaterialXDO xdo);
List<MaterialExportTestVO> convertList03(List<MaterialXDO> list);
}

@ -0,0 +1,71 @@
package com.yunxi.scm.module.demo.dal.dataobject.material;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yunxi.scm.framework.mybatis.core.dataobject.BaseDO;
import com.yunxi.scm.framework.mybatis.core.type.StringListTypeHandler;
import lombok.*;
import java.math.BigDecimal;
import java.util.List;
/**
* DO
*
* @author ccongli
*/
@TableName(value = "demo_material",autoResultMap = true)
@KeySequence("demo_material_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MaterialDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
*
*/
private String name;
/**
*
*
* {@link TODO material_status }
*/
private Byte status;
/**
*
*/
private Byte type;
/**
*
*/
// @TableField(typeHandler = JacksonTypeHandler.class)
@TableField(typeHandler = StringListTypeHandler.class)
private List<String> categories;
/**
*
*/
private String imgurl;
/**
*
*/
private Integer stock;
/**
*
*/
private BigDecimal price;
/**
*
*/
private String remark;
}

@ -0,0 +1,30 @@
package com.yunxi.scm.module.demo.dal.dataobject.material;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yunxi.scm.framework.mybatis.core.type.EncryptTypeHandler;
import com.yunxi.scm.framework.mybatis.core.type.StringListTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "demo_xxx", autoResultMap = true)
public class MaterialXDO implements Serializable {
@TableId
private Long id;
// 字段加密注解
@TableField(typeHandler = EncryptTypeHandler.class)
private String password;
@TableField(typeHandler = StringListTypeHandler.class)
private List<String> category;
}

@ -0,0 +1,15 @@
package com.yunxi.scm.module.demo.dal.mysql.material;
import com.yunxi.scm.framework.mybatis.core.mapper.BaseMapperX;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialXDO;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
*
* @author ccongli
*/
@Mapper
public interface MaterialXMapper extends BaseMapperX<MaterialXDO> {
}

@ -0,0 +1,41 @@
package com.yunxi.scm.module.demo.dal.mysql.material;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.framework.mybatis.core.mapper.BaseMapperX;
import com.yunxi.scm.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialExportReqVO;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialPageReqVO;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* Mapper
*
* @author ccongli
*/
@Mapper
public interface PMaterialMapper extends BaseMapperX<MaterialDO> {
default PageResult<MaterialDO> selectPage(MaterialPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<MaterialDO>()
.likeIfPresent(MaterialDO::getName, reqVO.getName())
.eqIfPresent(MaterialDO::getStatus, reqVO.getStatus())
.eqIfPresent(MaterialDO::getType, reqVO.getType())
.likeIfPresent(MaterialDO::getCategories, reqVO.getCategory())
.betweenIfPresent(MaterialDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MaterialDO::getId));
}
default List<MaterialDO> selectList(MaterialExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<MaterialDO>()
.likeIfPresent(MaterialDO::getName, reqVO.getName())
.eqIfPresent(MaterialDO::getStatus, reqVO.getStatus())
.eqIfPresent(MaterialDO::getType, reqVO.getType())
.likeIfPresent(MaterialDO::getCategories, reqVO.getCategory())
.betweenIfPresent(MaterialDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MaterialDO::getId));
}
}

@ -0,0 +1,34 @@
package com.yunxi.scm.module.demo.enums.material;
import com.yunxi.scm.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@Getter
@AllArgsConstructor
public enum CategoryEnum implements IntArrayValuable {
COMMON(0, "普通"),
MIAOSHA(1, "秒杀"),
PINTUAN(2,"拼团"),
KANJIA(3, "砍价");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CategoryEnum::getCode).toArray();
/**
*
*/
private final Integer code;
/**
*
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

@ -0,0 +1,24 @@
package com.yunxi.scm.module.demo.framework.web.config;
import com.yunxi.scm.framework.swagger.config.YunxiSwaggerAutoConfiguration;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* system web Configuration
*
* @author
*/
@Configuration(proxyBeanMethods = false)
public class DemoWebConfiguration {
/**
* demo API
*/
@Bean
public GroupedOpenApi dempGroupedOpenApi() {
return YunxiSwaggerAutoConfiguration.buildGroupedOpenApi("demo");
}
}

@ -0,0 +1,4 @@
/**
* system web
*/
package com.yunxi.scm.module.demo.framework.web;

@ -0,0 +1,70 @@
package com.yunxi.scm.module.demo.service.material;
import java.util.*;
import javax.validation.*;
import com.yunxi.scm.module.demo.controller.admin.material.vo.*;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialDO;
import com.yunxi.scm.framework.common.pojo.PageResult;
/**
* Service
*
* @author ccongli
*/
public interface PMaterialService {
/**
*
*
* @param createReqVO
* @return
*/
Long createMaterial(@Valid MaterialCreateReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateMaterial(@Valid MaterialUpdateReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteMaterial(Long id);
/**
*
*
* @param id
* @return
*/
MaterialDO getMaterial(Long id);
/**
*
*
* @param ids
* @return
*/
List<MaterialDO> getMaterialList(Collection<Long> ids);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<MaterialDO> getMaterialPage(MaterialPageReqVO pageReqVO);
/**
* , Excel
*
* @param exportReqVO
* @return
*/
List<MaterialDO> getMaterialList(MaterialExportReqVO exportReqVO);
}

@ -0,0 +1,85 @@
package com.yunxi.scm.module.demo.service.material;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialCreateReqVO;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialExportReqVO;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialPageReqVO;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialUpdateReqVO;
import com.yunxi.scm.module.demo.convert.material.MaterialConvert;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialDO;
import com.yunxi.scm.module.demo.dal.mysql.material.PMaterialMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import static com.yunxi.scm.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yunxi.scm.module.demo.enums.ErrorCodeConstants.MATERIAL_NOT_EXISTS;
/**
* Service
*
* @author ccongli
*/
@Service
@Validated
public class PMaterialServiceImpl implements PMaterialService {
@Resource
private PMaterialMapper materialMapper;
@Override
public Long createMaterial(MaterialCreateReqVO createReqVO) {
// 插入
MaterialDO material = MaterialConvert.INSTANCE.convert(createReqVO);
materialMapper.insert(material);
// 返回
return material.getId();
}
@Override
public void updateMaterial(MaterialUpdateReqVO updateReqVO) {
// 校验存在
validateMaterialExists(updateReqVO.getId());
// 更新
MaterialDO updateObj = MaterialConvert.INSTANCE.convert(updateReqVO);
materialMapper.updateById(updateObj);
}
@Override
public void deleteMaterial(Long id) {
// 校验存在
validateMaterialExists(id);
// 删除
materialMapper.deleteById(id);
}
private void validateMaterialExists(Long id) {
if (materialMapper.selectById(id) == null) {
throw exception(MATERIAL_NOT_EXISTS);
}
}
@Override
public MaterialDO getMaterial(Long id) {
return materialMapper.selectById(id);
}
@Override
public List<MaterialDO> getMaterialList(Collection<Long> ids) {
return materialMapper.selectBatchIds(ids);
}
@Override
public PageResult<MaterialDO> getMaterialPage(MaterialPageReqVO pageReqVO) {
return materialMapper.selectPage(pageReqVO);
}
@Override
public List<MaterialDO> getMaterialList(MaterialExportReqVO exportReqVO) {
return materialMapper.selectList(exportReqVO);
}
}

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunxi.scm.module.demo.dal.mysql.material.PMaterialMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

@ -0,0 +1,179 @@
package com.yunxi.scm.module.demo.service.material;
import com.yunxi.scm.framework.common.pojo.PageResult;
import com.yunxi.scm.framework.test.core.ut.BaseDbUnitTest;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialCreateReqVO;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialExportReqVO;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialPageReqVO;
import com.yunxi.scm.module.demo.controller.admin.material.vo.MaterialUpdateReqVO;
import com.yunxi.scm.module.demo.dal.dataobject.material.MaterialDO;
import com.yunxi.scm.module.demo.dal.mysql.material.PMaterialMapper;
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 com.yunxi.scm.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
import static com.yunxi.scm.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static com.yunxi.scm.framework.test.core.util.AssertUtils.assertPojoEquals;
import static com.yunxi.scm.framework.test.core.util.AssertUtils.assertServiceException;
import static com.yunxi.scm.framework.test.core.util.RandomUtils.randomLongId;
import static com.yunxi.scm.framework.test.core.util.RandomUtils.randomPojo;
import static com.yunxi.scm.module.demo.enums.ErrorCodeConstants.MATERIAL_NOT_EXISTS;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link PMaterialServiceImpl}
*
* @author ccongli
*/
@Import(PMaterialServiceImpl.class)
public class MaterialServiceImplTest extends BaseDbUnitTest {
@Resource
private PMaterialServiceImpl materialService;
@Resource
private PMaterialMapper materialMapper;
@Test
public void testCreateMaterial_success() {
// 准备参数
MaterialCreateReqVO reqVO = randomPojo(MaterialCreateReqVO.class);
// 调用
Long materialId = materialService.createMaterial(reqVO);
// 断言
assertNotNull(materialId);
// 校验记录的属性是否正确
MaterialDO material = materialMapper.selectById(materialId);
assertPojoEquals(reqVO, material);
}
@Test
public void testUpdateMaterial_success() {
// mock 数据
MaterialDO dbMaterial = randomPojo(MaterialDO.class);
materialMapper.insert(dbMaterial);// @Sql: 先插入出一条存在的数据
// 准备参数
MaterialUpdateReqVO reqVO = randomPojo(MaterialUpdateReqVO.class, o -> {
o.setId(dbMaterial.getId()); // 设置更新的 ID
});
// 调用
materialService.updateMaterial(reqVO);
// 校验是否更新正确
MaterialDO material = materialMapper.selectById(reqVO.getId()); // 获取最新的
assertPojoEquals(reqVO, material);
}
@Test
public void testUpdateMaterial_notExists() {
// 准备参数
MaterialUpdateReqVO reqVO = randomPojo(MaterialUpdateReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> materialService.updateMaterial(reqVO), MATERIAL_NOT_EXISTS);
}
@Test
public void testDeleteMaterial_success() {
// mock 数据
MaterialDO dbMaterial = randomPojo(MaterialDO.class);
materialMapper.insert(dbMaterial);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbMaterial.getId();
// 调用
materialService.deleteMaterial(id);
// 校验数据不存在了
assertNull(materialMapper.selectById(id));
}
@Test
public void testDeleteMaterial_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> materialService.deleteMaterial(id), MATERIAL_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetMaterialPage() {
// mock 数据
MaterialDO dbMaterial = randomPojo(MaterialDO.class, o -> { // 等会查询到
o.setName(null);
o.setStatus(null);
o.setType(null);
o.setCategories(null);
o.setCreateTime(null);
});
materialMapper.insert(dbMaterial);
// 测试 name 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setName(null)));
// 测试 status 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setStatus(null)));
// 测试 type 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setType(null)));
// 测试 category 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setCategories(null)));
// 测试 createTime 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setCreateTime(null)));
// 准备参数
MaterialPageReqVO reqVO = new MaterialPageReqVO();
reqVO.setName(null);
reqVO.setStatus(null);
reqVO.setType(null);
reqVO.setCategory(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<MaterialDO> pageResult = materialService.getMaterialPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbMaterial, pageResult.getList().get(0));
}
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetMaterialList() {
// mock 数据
MaterialDO dbMaterial = randomPojo(MaterialDO.class, o -> { // 等会查询到
o.setName(null);
o.setStatus(null);
o.setType(null);
o.setCategories(null);
o.setCreateTime(null);
});
materialMapper.insert(dbMaterial);
// 测试 name 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setName(null)));
// 测试 status 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setStatus(null)));
// 测试 type 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setType(null)));
// 测试 category 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setCategories(null)));
// 测试 createTime 不匹配
materialMapper.insert(cloneIgnoreId(dbMaterial, o -> o.setCreateTime(null)));
// 准备参数
MaterialExportReqVO reqVO = new MaterialExportReqVO();
reqVO.setName(null);
reqVO.setStatus(null);
reqVO.setType(null);
reqVO.setCategory(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
List<MaterialDO> list = materialService.getMaterialList(reqVO);
// 断言
assertEquals(1, list.size());
assertPojoEquals(dbMaterial, list.get(0));
}
}

@ -0,0 +1,2 @@
-- SQL yunxi-module-demo-biz test/resources/sql/clean.sql
DELETE FROM "demo_material";

@ -0,0 +1,19 @@
-- SQL yunxi-module-demo-biz test/resources/sql/create_tables.sql
CREATE TABLE IF NOT EXISTS "demo_material" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar NOT NULL,
"status" varchar NOT NULL,
"type" varchar NOT NULL,
"category" varchar NOT NULL,
"imgurl" varchar NOT NULL,
"stock" int NOT NULL,
"price" varchar NOT NULL,
"remark" varchar,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint NOT NULL,
PRIMARY KEY ("id")
) COMMENT '';

@ -0,0 +1,55 @@
-- SQL
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status, component_name
)
VALUES (
'', '', 2, 0, 1,
'material', '', 'demo/material/index', 0, 'Material'
);
-- ID
-- MySQL OraclePostgreSQLSQLServer @parentId
SELECT @parentId := LAST_INSERT_ID();
-- SQL
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'', 'demo:material:query', 3, 1, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'', 'demo:material:create', 3, 2, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'', 'demo:material:update', 3, 3, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'', 'demo:material:delete', 3, 4, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'', 'demo:material:export', 3, 5, @parentId,
'', '', '', 0
);
Loading…
Cancel
Save