1:产品模块添加 2:添加Es测试

This commit is contained in:
xuelijun
2025-04-21 11:16:24 +08:00
parent 98f55d2d09
commit 0e5639715e
35 changed files with 1775 additions and 9 deletions

View File

@@ -13,6 +13,7 @@
<modules>
<module>tashow-module-system</module>
<module>tashow-module-infra</module>
<module>tashow-module-product</module>
</modules>
</project>

View File

@@ -1,9 +0,0 @@
/**
* infra 模块,主要提供两块能力:
* 1. 我们放基础设施的运维与管理,支撑上层的通用与核心业务。 例如说:定时任务的管理、服务器的信息等等
* 2. 研发工具,提升研发效率与质量。 例如说:代码生成器、接口文档等等
*
* 1. Controller URL以 /infra/ 开头,避免和其它 Module 冲突
* 2. DataObject 表名:以 infra_ 开头,方便在数据库中区分
*/
package com.tashow.cloud.infra;

View File

@@ -0,0 +1,23 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-module</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>tashow-module-product-api</module>
<module>tashow-module-product-biz</module>
</modules>
<artifactId>tashow-module-product</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
system 模块下,我们放通用业务,支撑上层的核心业务。
例如说:用户、部门、权限、数据字典等等
</description>
</project>

View File

@@ -0,0 +1,39 @@
<?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>com.tashow.cloud</groupId>
<artifactId>tashow-module-product</artifactId>
<version>${revision}</version>
</parent>
<artifactId>tashow-module-product-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
infra 模块 API暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-common</artifactId>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,23 @@
package com.tashow.cloud.productapi.enums;
import com.tashow.cloud.common.enums.RpcConstants;
/**
* API 相关的枚举
*
* @author 芋道源码
*/
public class ApiConstants {
/**
* 服务名
*
* 注意,需要保证和 spring.application.name 保持一致
*/
public static final String NAME = "product-server";
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/product";
public static final String VERSION = "1.0.0";
}

View File

@@ -0,0 +1,12 @@
package com.tashow.cloud.productapi.enums;
/**
* product 字典类型的枚举类
*
* @author HUIHUI
*/
public interface DictTypeConstants {
String PRODUCT_SPU_STATUS = "product_spu_status"; // 商品 SPU 状态
}

View File

@@ -0,0 +1,56 @@
package com.tashow.cloud.productapi.enums;
import com.tashow.cloud.common.exception.ErrorCode;
/**
* Product 错误码枚举类
*
* product 系统,使用 1-008-000-000 段
*/
public interface ErrorCodeConstants {
// ========== 商品分类相关 1-008-001-000 ============
ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1_008_001_000, "商品分类不存在");
ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1_008_001_001, "父分类不存在");
ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1_008_001_002, "父分类不能是二级分类");
ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1_008_001_003, "存在子分类,无法删除");
ErrorCode CATEGORY_DISABLED = new ErrorCode(1_008_001_004, "商品分类({})已禁用,无法使用");
ErrorCode CATEGORY_HAVE_BIND_SPU = new ErrorCode(1_008_001_005, "类别下存在商品,无法删除");
// ========== 商品品牌相关编号 1-008-002-000 ==========
ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1_008_002_000, "品牌不存在");
ErrorCode BRAND_DISABLED = new ErrorCode(1_008_002_001, "品牌已禁用");
ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1_008_002_002, "品牌名称已存在");
// ========== 商品属性项 1-008-003-000 ==========
ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1_008_003_000, "属性项不存在");
ErrorCode PROPERTY_EXISTS = new ErrorCode(1_008_003_001, "属性项的名称已存在");
ErrorCode PROPERTY_DELETE_FAIL_VALUE_EXISTS = new ErrorCode(1_008_003_002, "属性项下存在属性值,无法删除");
// ========== 商品属性值 1-008-004-000 ==========
ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1_008_004_000, "属性值不存在");
ErrorCode PROPERTY_VALUE_EXISTS = new ErrorCode(1_008_004_001, "属性值的名称已存在");
// ========== 商品 SPU 1-008-005-000 ==========
ErrorCode SPU_NOT_EXISTS = new ErrorCode(1_008_005_000, "商品 SPU 不存在");
ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1_008_005_001, "商品分类不正确,原因:必须使用第二级的商品分类及以下");
ErrorCode SPU_SAVE_FAIL_COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1_008_005_002, "商品 SPU 保存失败,原因:优惠劵不存在");
ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_003, "商品 SPU【{}】不处于上架状态");
ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1_008_005_004, "商品 SPU 不处于回收站状态");
// ========== 商品 SKU 1-008-006-000 ==========
ErrorCode SKU_NOT_EXISTS = new ErrorCode(1_008_006_000, "商品 SKU 不存在");
ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1_008_006_001, "商品 SKU 的属性组合存在重复");
ErrorCode SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1_008_006_002, "一个 SPU 下的每个 SKU其属性项必须一致");
ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1_008_006_003, "一个 SPU 下的每个 SKU必须不重复");
ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1_008_006_004, "商品 SKU 库存不足");
// ========== 商品 评价 1-008-007-000 ==========
ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1_008_007_000, "商品评价不存在");
ErrorCode COMMENT_ORDER_EXISTS = new ErrorCode(1_008_007_001, "订单的商品评价已存在");
// ========== 商品 收藏 1-008-008-000 ==========
ErrorCode FAVORITE_EXISTS = new ErrorCode(1_008_008_000, "该商品已经被收藏");
ErrorCode FAVORITE_NOT_EXISTS = new ErrorCode(1_008_008_001, "商品收藏不存在");
}

View File

@@ -0,0 +1,15 @@
package com.tashow.cloud.productapi.enums;
/**
* Product 常量
*
* @author HUIHUI
*/
public interface ProductConstants {
/**
* 警戒库存 TODO 警戒库存暂时为 10后期需要使用常量或者数据库配置替换
*/
int ALERT_STOCK = 10;
}

View File

@@ -0,0 +1,38 @@
package com.tashow.cloud.productapi.enums.comment;
import com.tashow.cloud.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 商品评论的审批状态枚举
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum ProductCommentAuditStatusEnum implements ArrayValuable<Integer> {
NONE(0, "待审核"),
APPROVE(1, "审批通过"),
REJECT(2, "审批不通过"),;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(ProductCommentAuditStatusEnum::getStatus).toArray(Integer[]::new);
/**
* 审批状态
*/
private final Integer status;
/**
* 状态名
*/
private final String name;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,41 @@
package com.tashow.cloud.productapi.enums.comment;
import com.tashow.cloud.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 商品评论的星级枚举
*
* @author wangzhs
*/
@Getter
@AllArgsConstructor
public enum ProductCommentScoresEnum implements ArrayValuable<Integer> {
ONE(1, "1星"),
TWO(2, "2星"),
THREE(3, "3星"),
FOUR(4, "4星"),
FIVE(5, "5星");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(ProductCommentScoresEnum::getScores).toArray(Integer[]::new);
/**
* 星级
*/
private final Integer scores;
/**
* 星级名
*/
private final String name;
@Override
public Integer[] array() {
return ARRAYS;
}
}

View File

@@ -0,0 +1,48 @@
package com.tashow.cloud.productapi.enums.spu;
import com.tashow.cloud.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 商品 SPU 状态
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum ProductSpuStatusEnum implements ArrayValuable<Integer> {
RECYCLE(-1, "回收站"),
DISABLE(0, "下架"),
ENABLE(1, "上架");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(ProductSpuStatusEnum::getStatus).toArray(Integer[]::new);
/**
* 状态
*/
private final Integer status;
/**
* 状态名
*/
private final String name;
@Override
public Integer[] array() {
return ARRAYS;
}
/**
* 判断是否处于【上架】状态
*
* @param status 状态
* @return 是否处于【上架】状态
*/
public static boolean isEnable(Integer status) {
return ENABLE.getStatus().equals(status);
}
}

View File

@@ -0,0 +1,19 @@
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
## 感谢复旦核博士的建议!灰子哥,牛皮!
FROM eclipse-temurin:8-jre
## 创建目录,并使用它作为工作目录
RUN mkdir -p /yudao-module-product-biz
WORKDIR /yudao-module-product-biz
## 将后端项目的 Jar 文件,复制到镜像中
COPY ./target/yudao-module-product-biz.jar app.jar
## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m"
## 暴露后端项目的 48080 端口
EXPOSE 48100
## 启动后端项目
CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

View File

@@ -0,0 +1,136 @@
<?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>com.tashow.cloud</groupId>
<artifactId>tashow-module-product</artifactId>
<version>${revision}</version>
</parent>
<artifactId>tashow-module-product-biz</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
infra 模块,主要提供两块能力:
1. 我们放基础设施的运维与管理,支撑上层的通用与核心业务。 例如说:定时任务的管理、服务器的信息等等
2. 研发工具,提升研发效率与质量。 例如说:代码生成器、接口文档等等
</description>
<dependencies>
<!-- Spring Cloud 基础 -->
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-framework-env</artifactId>
</dependency>
<!-- 依赖服务 -->
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-module-product-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- <dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-member-api</artifactId>
<version>${revision}</version>
</dependency>
-->
<!-- 业务组件 -->
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-data-permission</artifactId>
</dependency>
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-data-es</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-framework-tenant</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-framework-security</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-data-mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-data-redis</artifactId>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-framework-rpc</artifactId>
</dependency>
<!-- Registry 注册中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Config 配置中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-data-excel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>3.4.1</version>
<scope>compile</scope>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>com.tashow.cloud</groupId>
<artifactId>tashow-framework-monitor</artifactId>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,24 @@
package com.tashow.cloud.productbiz;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 项目的启动类
*
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
*
* @author 芋道源码
*/
@SpringBootApplication
public class ProductServerApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServerApplication.class, args);
System.out.println("启动成功");
}
}

View File

@@ -0,0 +1,59 @@
package com.tashow.cloud.productbiz.controller.app;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import com.tashow.cloud.common.pojo.CommonResult;
import com.tashow.cloud.productbiz.dal.dataobject.Product;
import com.tashow.cloud.productbiz.service.ProductSearchService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.List;
import static com.tashow.cloud.common.pojo.CommonResult.success;
@Tag(name = "product")
@RestController
@PermitAll
@RequestMapping("/product/es")
@Validated
public class Test {
@Autowired
private ElasticsearchClient esClient;
@Autowired
private ProductSearchService productSearchService;
@GetMapping("/testes")
@Operation(summary = "es插入测试")
@PermitAll
public CommonResult<String> testes() {
// 准备测试数据
Product product = new Product();
product.setId(1L);
product.setName("测试");
// 调用被测试方法
productSearchService.indexProduct(product);
return success("成功");
}
@GetMapping("/gettest")
@Operation(summary = "es查询测试")
@PermitAll
public CommonResult<String> gettest() {
// 执行测试
List<Product> results = productSearchService.searchProducts("测试");
System.out.println("==="+results);
return success("成功");
}
}

View File

@@ -0,0 +1,56 @@
package com.tashow.cloud.productbiz.dal.dataobject;
import lombok.Data;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.*;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Data
@Document(indexName = "products")
public class Product {
// 主键使用标准Spring Data注解
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Text, analyzer = "ik_smart")
private String subtitle;
@Field(type = FieldType.Keyword)
private List<String> keywords;
@Field(type = FieldType.Double)
private BigDecimal price;
@Field(type = FieldType.Integer)
private Integer sales;
@Field(type = FieldType.Boolean)
private Boolean onSale;
@Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
private LocalDateTime createTime;
// 嵌套对象示例
@Field(type = FieldType.Nested)
private Category category;
@Data
public static class Category {
@Field(type = FieldType.Long)
private Long id;
@Field(type = FieldType.Keyword)
private String name;
}
}

View File

@@ -0,0 +1,53 @@
package com.tashow.cloud.productbiz.dal.dataobject.brand;
import com.tashow.cloud.common.enums.CommonStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import lombok.*;
/**
* 商品品牌 DO
*
* @author 芋道源码
*/
@TableName("product_brand")
@KeySequence("product_brand_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductBrandDO extends BaseDO {
/**
* 品牌编号
*/
@TableId
private Long id;
/**
* 品牌名称
*/
private String name;
/**
* 品牌图片
*/
private String picUrl;
/**
* 品牌排序
*/
private Integer sort;
/**
* 品牌描述
*/
private String description;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
}

View File

@@ -0,0 +1,64 @@
package com.tashow.cloud.productbiz.dal.dataobject.category;
import com.tashow.cloud.common.enums.CommonStatusEnum;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品分类 DO
*
* @author 芋道源码
*/
@TableName("product_category")
@KeySequence("product_category_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductCategoryDO extends BaseDO {
/**
* 父分类编号 - 根分类
*/
public static final Long PARENT_ID_NULL = 0L;
/**
* 限定分类层级
*/
public static final int CATEGORY_LEVEL = 2;
/**
* 分类编号
*/
@TableId
private Long id;
/**
* 父分类编号
*/
private Long parentId;
/**
* 分类名称
*/
private String name;
/**
* 移动端分类图
*
* 建议 180*180 分辨率
*/
private String picUrl;
/**
* 分类排序
*/
private Integer sort;
/**
* 开启状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
}

View File

@@ -0,0 +1,159 @@
package com.tashow.cloud.productbiz.dal.dataobject.comment;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import com.tashow.cloud.productbiz.dal.dataobject.sku.ProductSkuDO;
import com.tashow.cloud.productbiz.dal.dataobject.spu.ProductSpuDO;
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.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.time.LocalDateTime;
import java.util.List;
/**
* 商品评论 DO
*
* @author 芋道源码
*/
@TableName(value = "product_comment", autoResultMap = true)
@KeySequence("product_comment_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductCommentDO extends BaseDO {
/**
* 默认匿名昵称
*/
public static final String NICKNAME_ANONYMOUS = "匿名用户";
/**
* 评论编号,主键自增
*/
@TableId
private Long id;
/**
* 评价人的用户编号
*
* 关联 MemberUserDO 的 id 编号
*/
private Long userId;
/**
* 评价人名称
*/
private String userNickname;
/**
* 评价人头像
*/
private String userAvatar;
/**
* 是否匿名
*/
private Boolean anonymous;
/**
* 交易订单编号
*
* 关联 TradeOrderDO 的 id 编号
*/
private Long orderId;
/**
* 交易订单项编号
*
* 关联 TradeOrderItemDO 的 id 编号
*/
private Long orderItemId;
/**
* 商品 SPU 编号
*
* 关联 {@link ProductSpuDO#getId()}
*/
private Long spuId;
/**
* 商品 SPU 名称
*
* 关联 {@link ProductSpuDO#getName()}
*/
private String spuName;
/**
* 商品 SKU 编号
*
* 关联 {@link ProductSkuDO#getId()}
*/
private Long skuId;
/**
* 商品 SKU 图片地址
*
* 关联 {@link ProductSkuDO#getPicUrl()}
*/
private String skuPicUrl;
/**
* 属性数组JSON 格式
*
* 关联 {@link ProductSkuDO#getProperties()}
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<ProductSkuDO.Property> skuProperties;
/**
* 是否可见
*
* true:显示
* false:隐藏
*/
private Boolean visible;
/**
* 评分星级
*
* 1-5 分
*/
private Integer scores;
/**
* 描述星级
*
* 1-5 星
*/
private Integer descriptionScores;
/**
* 服务星级
*
* 1-5 星
*/
private Integer benefitScores;
/**
* 评论内容
*/
private String content;
/**
* 评论图片地址数组
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> picUrls;
/**
* 商家是否回复
*/
private Boolean replyStatus;
/**
* 回复管理员编号
* 关联 AdminUserDO 的 id 编号
*/
private Long replyUserId;
/**
* 商家回复内容
*/
private String replyContent;
/**
* 商家回复时间
*/
private LocalDateTime replyTime;
}

View File

@@ -0,0 +1,43 @@
package com.tashow.cloud.productbiz.dal.dataobject.favorite;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import com.tashow.cloud.productbiz.dal.dataobject.spu.ProductSpuDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品收藏 DO
*
* @author 芋道源码
*/
@TableName("product_favorite")
@KeySequence("product_favorite_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductFavoriteDO extends BaseDO {
/**
* 编号,主键自增
*/
@TableId
private Long id;
/**
* 用户编号
*
* 关联 MemberUserDO 的 id 编号
*/
private Long userId;
/**
* 商品 SPU 编号
*
* 关联 {@link ProductSpuDO#getId()}
*/
private Long spuId;
}

View File

@@ -0,0 +1,42 @@
package com.tashow.cloud.productbiz.dal.dataobject.history;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品浏览记录 DO
*
* @author owen
*/
@TableName("product_browse_history")
@KeySequence("product_browse_history_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductBrowseHistoryDO extends BaseDO {
/**
* 记录编号
*/
@TableId
private Long id;
/**
* 商品 SPU 编号
*/
private Long spuId;
/**
* 用户编号
*/
private Long userId;
/**
* 用户是否删除
*/
private Boolean userDeleted;
}

View File

@@ -0,0 +1,47 @@
package com.tashow.cloud.productbiz.dal.dataobject.property;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品属性项 DO
*
* @author 芋道源码
*/
@TableName("product_property")
@KeySequence("product_property_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductPropertyDO extends BaseDO {
/**
* SPU 单规格时,默认属性 id
*/
public static final Long ID_DEFAULT = 0L;
/**
* SPU 单规格时,默认属性名字
*/
public static final String NAME_DEFAULT = "默认";
/**
* 主键
*/
@TableId
private Long id;
/**
* 名称
*/
private String name;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,55 @@
package com.tashow.cloud.productbiz.dal.dataobject.property;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品属性值 DO
*
* @author 芋道源码
*/
@TableName("product_property_value")
@KeySequence("product_property_value_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductPropertyValueDO extends BaseDO {
/**
* SPU 单规格时,默认属性值 id
*/
public static final Long ID_DEFAULT = 0L;
/**
* SPU 单规格时,默认属性值名字
*/
public static final String NAME_DEFAULT = "默认";
/**
* 主键
*/
@TableId
private Long id;
/**
* 属性项的编号
*
* 关联 {@link ProductPropertyDO#getId()}
*/
private Long propertyId;
/**
* 名称
*/
private String name;
/**
* 备注
*
*/
private String remark;
}

View File

@@ -0,0 +1,134 @@
package com.tashow.cloud.productbiz.dal.dataobject.sku;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import com.tashow.cloud.productbiz.dal.dataobject.property.ProductPropertyDO;
import com.tashow.cloud.productbiz.dal.dataobject.property.ProductPropertyValueDO;
import com.tashow.cloud.productbiz.dal.dataobject.spu.ProductSpuDO;
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.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.util.List;
/**
* 商品 SKU DO
*
* @author 芋道源码
*/
@TableName(value = "product_sku", autoResultMap = true)
@KeySequence("product_sku_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductSkuDO extends BaseDO {
/**
* 商品 SKU 编号,自增
*/
@TableId
private Long id;
/**
* SPU 编号
*
* 关联 {@link ProductSpuDO#getId()}
*/
private Long spuId;
/**
* 属性数组JSON 格式
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<Property> properties;
/**
* 商品价格,单位:分
*/
private Integer price;
/**
* 市场价,单位:分
*/
private Integer marketPrice;
/**
* 成本价,单位:分
*/
private Integer costPrice;
/**
* 商品条码
*/
private String barCode;
/**
* 图片地址
*/
private String picUrl;
/**
* 库存
*/
private Integer stock;
/**
* 商品重量单位kg 千克
*/
private Double weight;
/**
* 商品体积单位m^3 平米
*/
private Double volume;
/**
* 一级分销的佣金,单位:分
*/
private Integer firstBrokeragePrice;
/**
* 二级分销的佣金,单位:分
*/
private Integer secondBrokeragePrice;
// ========== 营销相关字段 =========
// ========== 统计相关字段 =========
/**
* 商品销量
*/
private Integer salesCount;
/**
* 商品属性
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Property {
/**
* 属性编号
* 关联 {@link ProductPropertyDO#getId()}
*/
private Long propertyId;
/**
* 属性名字
* 冗余 {@link ProductPropertyDO#getName()}
*
* 注意:每次属性名字发生变化时,需要更新该冗余
*/
private String propertyName;
/**
* 属性值编号
* 关联 {@link ProductPropertyValueDO#getId()}
*/
private Long valueId;
/**
* 属性值名字
* 冗余 {@link ProductPropertyValueDO#getName()}
*
* 注意:每次属性值名字发生变化时,需要更新该冗余
*/
private String valueName;
}
}

View File

@@ -0,0 +1,170 @@
package com.tashow.cloud.productbiz.dal.dataobject.spu;
import com.tashow.cloud.mybatis.mybatis.core.dataobject.BaseDO;
import com.tashow.cloud.mybatis.mybatis.core.type.IntegerListTypeHandler;
import com.tashow.cloud.productbiz.dal.dataobject.brand.ProductBrandDO;
import com.tashow.cloud.productbiz.dal.dataobject.category.ProductCategoryDO;
import com.tashow.cloud.productbiz.dal.dataobject.sku.ProductSkuDO;
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.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.util.List;
/**
* 商品 SPU DO
*
* @author 芋道源码
*/
@TableName(value = "product_spu", autoResultMap = true)
@KeySequence("product_spu_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductSpuDO extends BaseDO {
/**
* 商品 SPU 编号,自增
*/
@TableId
private Long id;
// ========== 基本信息 =========
/**
* 商品名称
*/
private String name;
/**
* 关键字
*/
private String keyword;
/**
* 商品简介
*/
private String introduction;
/**
* 商品详情
*/
private String description;
/**
* 商品分类编号
*
* 关联 {@link ProductCategoryDO#getId()}
*/
private Long categoryId;
/**
* 商品品牌编号
*
* 关联 {@link ProductBrandDO#getId()}
*/
private Long brandId;
/**
* 商品封面图
*/
private String picUrl;
/**
* 商品轮播图
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> sliderPicUrls;
/**
* 排序字段
*/
private Integer sort;
/**
* 商品状态
*
* 枚举 {@link ProductSpuStatusEnum}
*/
private Integer status;
// ========== SKU 相关字段 =========
/**
* 规格类型
*
* false - 单规格
* true - 多规格
*/
private Boolean specType;
/**
* 商品价格,单位使用:分
*
* 基于其对应的 {@link ProductSkuDO#getPrice()} sku单价最低的商品的
*/
private Integer price;
/**
* 市场价,单位使用:分
*
* 基于其对应的 {@link ProductSkuDO#getMarketPrice()} sku单价最低的商品的
*/
private Integer marketPrice;
/**
* 成本价,单位使用:分
*
* 基于其对应的 {@link ProductSkuDO#getCostPrice()} sku单价最低的商品的
*/
private Integer costPrice;
/**
* 库存
*
* 基于其对应的 {@link ProductSkuDO#getStock()} 求和
*/
private Integer stock;
// ========== 物流相关字段 =========
/**
* 配送方式数组
*
* 对应 DeliveryTypeEnum 枚举
*/
@TableField(typeHandler = IntegerListTypeHandler.class)
private List<Integer> deliveryTypes;
/**
* 物流配置模板编号
*
* 对应 TradeDeliveryExpressTemplateDO 的 id 编号
*/
private Long deliveryTemplateId;
// ========== 营销相关字段 =========
/**
* 赠送积分
*/
private Integer giveIntegral;
// TODO @puhui999字段估计要改成 brokerageType
/**
* 分销类型
*
* false - 默认
* true - 自行设置
*/
private Boolean subCommissionType;
// ========== 统计相关字段 =========
/**
* 商品销量
*/
private Integer salesCount;
/**
* 虚拟销量
*/
private Integer virtualSalesCount;
/**
* 浏览量
*/
private Integer browseCount;
}

View File

@@ -0,0 +1,39 @@
package com.tashow.cloud.productbiz.framework.security.config;
import com.tashow.cloud.productapi.enums.ApiConstants;
import com.tashow.cloud.security.security.config.AuthorizeRequestsCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
/**
* Product 模块的 Security 配置
*/
@Configuration("productSecurityConfiguration")
public class SecurityConfiguration {
@Bean("productAuthorizeRequestsCustomizer")
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
return new AuthorizeRequestsCustomizer() {
@Override
public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
// Swagger 接口文档
registry.requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers("/webjars/**").permitAll()
.requestMatchers("/swagger-ui").permitAll()
.requestMatchers("/swagger-ui/**").permitAll();
// Spring Boot Actuator 的安全配置
registry.requestMatchers("/actuator").permitAll()
.requestMatchers("/actuator/**").permitAll();
// Druid 监控
registry.requestMatchers("/druid/**").permitAll();
// RPC 服务的安全配置
registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll();
}
};
}
}

View File

@@ -0,0 +1,54 @@
package com.tashow.cloud.productbiz.service;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import com.tashow.cloud.productbiz.dal.dataobject.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
@Slf4j
public class ProductSearchService {
@Autowired
private ElasticsearchClient esClient;
public void indexProduct(Product product) {
try {
IndexResponse response = esClient.index(i -> i
.index("products")
.id(product.getId().toString())
.document(product));
log.info("产品索引成功, ID: {}", response.id());
} catch (IOException e) {
throw new RuntimeException("索引产品失败", e);
}
}
public List<Product> searchProducts(String keyword) {
try {
return esClient.search(s -> s
.index("products")
.query(q -> q
.match(m -> m
.field("name")
.query(keyword))),
Product.class)
.hits()
.hits()
.stream()
.map(hit -> hit.source()) // 新版API直接调用source()方法
.filter(Objects::nonNull) // 过滤掉source为null的结果
.collect(Collectors.toList());
} catch (IOException e) {
throw new RuntimeException("搜索产品失败", e);
}
}
}

View File

@@ -0,0 +1 @@
com.tashow.cloud.system.framework.captcha.core.RedisCaptchaServiceImpl

View File

@@ -0,0 +1,15 @@
spring:
cloud:
nacos:
server-addr: 43.139.42.137:8848 # Nacos 服务器地址
username: nacos # Nacos 账号
password: nacos # Nacos 密码
discovery: # 【配置中心】配置项
namespace: 76667956-2ac2-4e05-906b-4bca4ebcc5f0 # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
config: # 【注册中心】配置项
namespace: 76667956-2ac2-4e05-906b-4bca4ebcc5f0 # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP

View File

@@ -0,0 +1,17 @@
server:
port: 48071
spring:
application:
name: product-server
profiles:
active: local
config:
import:
- optional:classpath:application-${spring.profiles.active}.yaml # 加载【本地】配置
- optional:nacos:application.yaml # 加载【Nacos】通用的配置
- optional:nacos:tenant.yaml # 加载【Nacos】通用的配置
- optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml # 加载【Nacos】的配置

View File

@@ -0,0 +1,76 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<!-- 变量 yudao.info.base-package基础业务包 -->
<springProperty scope="context" name="tashow.info.base-package" source="tashow.info.base-package"/>
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度,%msg日志消息%n是换行符 -->
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 控制台 Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 文件 Appender -->
<!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
<!-- 日志文件名 -->
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 滚动后的日志文件名 -->
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<!-- 日志文件,到达多少容量,进行滚动 -->
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<!-- 日志文件的总大小0 表示不限制 -->
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<!-- 日志文件的保留天数 -->
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy>
</appender>
<!-- 异步写入日志,提升性能 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
<queueSize>256</queueSize>
<appender-ref ref="FILE"/>
</appender>
<!-- SkyWalking GRPC 日志收集实现日志中心。注意SkyWalking 8.4.0 版本开始支持 -->
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 本地环境 -->
<springProfile name="local">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
<appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
</root>
</springProfile>
<!-- 其它环境 -->
<springProfile name="dev,test,stage,prod,default">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC"/>
<appender-ref ref="GRPC"/>
</root>
</springProfile>
</configuration>

View File

@@ -0,0 +1,48 @@
spring:
main:
lazy-initialization: true # 开启懒加载,加快速度
banner-mode: off # 单元测试,禁用 Banner
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
datasource:
name: ruoyi-vue-pro
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式DATABASE_TO_UPPER 配置表和字段使用小写
driver-class-name: org.h2.Driver
username: sa
password:
druid:
async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
initial-size: 1 # 单元测试,配置为 1提升启动速度
sql:
init:
schema-locations: classpath:/sql/create_tables.sql
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:
host: 127.0.0.1 # 地址
port: 16379 # 端口(单元测试,使用 16379 端口)
database: 0 # 数据库索引
mybatis-plus:
lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
type-aliases-package: ${yudao.info.base-package}.dal.dataobject
--- #################### 定时任务相关配置 ####################
--- #################### 配置中心相关配置 ####################
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项(单元测试,禁用 Lock4j
--- #################### 监控相关配置 ####################
--- #################### 芋道相关配置 ####################
# 芋道配置项,设置当前项目所有自定义的配置
yudao:
info:
base-package: cn.iocoder.yudao.module.product

View File

@@ -0,0 +1,4 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
</configuration>

View File

@@ -0,0 +1,7 @@
DELETE FROM "product_sku";
DELETE FROM "product_spu";
DELETE FROM "product_category";
DELETE FROM "product_brand";
DELETE FROM "product_property";
DELETE FROM "product_property_value";
DELETE FROM "product_comment";

View File

@@ -0,0 +1,157 @@
CREATE TABLE IF NOT EXISTS `product_sku` (
`id` bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
`spu_id` bigint NOT NULL COMMENT 'spu编号',
`properties` varchar(512) DEFAULT NULL COMMENT '属性数组JSON 格式',
`price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位:分',
`market_price` int DEFAULT NULL COMMENT '市场价,单位:分',
`cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分',
`bar_code` varchar(64) DEFAULT NULL COMMENT 'SKU 的条形码',
`pic_url` varchar(256) NOT NULL COMMENT '图片地址',
`stock` int DEFAULT NULL COMMENT '库存',
`weight` double DEFAULT NULL COMMENT '商品重量单位kg 千克',
`volume` double DEFAULT NULL COMMENT '商品体积单位m^3 平米',
`sub_commission_first_price` int DEFAULT NULL COMMENT '一级分销的佣金,单位:分',
`sub_commission_second_price` int DEFAULT NULL COMMENT '二级分销的佣金,单位:分',
`sales_count` int DEFAULT NULL COMMENT '商品销量',
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY("id")
) COMMENT '商品sku';
CREATE TABLE IF NOT EXISTS `product_spu` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品 SPU 编号,自增',
`name` varchar(128) NOT NULL COMMENT '商品名称',
`keyword` varchar(256) NOT NULL COMMENT '关键字',
`introduction` varchar(256) NOT NULL COMMENT '商品简介',
`description` text NOT NULL COMMENT '商品详情',
`bar_code` varchar(64) NOT NULL COMMENT '条形码',
`category_id` bigint NOT NULL COMMENT '商品分类编号',
`brand_id` int DEFAULT NULL COMMENT '商品品牌编号',
`pic_url` varchar(256) NOT NULL COMMENT '商品封面图',
`slider_pic_urls` varchar(2000) DEFAULT '' COMMENT '商品轮播图地址\n 数组,以逗号分隔\n 最多上传15张',
`video_url` varchar(256) DEFAULT NULL COMMENT '商品视频',
`unit` tinyint NOT NULL COMMENT '单位',
`sort` int NOT NULL DEFAULT '0' COMMENT '排序字段',
`status` tinyint NOT NULL COMMENT '商品状态: 0 上架(开启) 1 下架(禁用)-1 回收',
`spec_type` bit(1) NOT NULL COMMENT '规格类型0 单规格 1 多规格',
`price` int NOT NULL DEFAULT '-1' COMMENT '商品价格,单位使用:分',
`market_price` int NOT NULL COMMENT '市场价,单位使用:分',
`cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分',
`stock` int NOT NULL DEFAULT '0' COMMENT '库存',
`delivery_template_id` bigint NOT NULL COMMENT '物流配置模板编号',
`recommend_hot` bit(1) NOT NULL COMMENT '是否热卖推荐: 0 默认 1 热卖',
`recommend_benefit` bit(1) NOT NULL COMMENT '是否优惠推荐: 0 默认 1 优选',
`recommend_best` bit(1) NOT NULL COMMENT '是否精品推荐: 0 默认 1 精品',
`recommend_new` bit(1) NOT NULL COMMENT '是否新品推荐: 0 默认 1 新品',
`recommend_good` bit(1) NOT NULL COMMENT '是否优品推荐',
`give_integral` int NOT NULL COMMENT '赠送积分',
`give_coupon_template_ids` varchar(512) DEFAULT '' COMMENT '赠送的优惠劵编号的数组',
`sub_commission_type` bit(1) NOT NULL COMMENT '分销类型',
`activity_orders` varchar(16) NOT NULL DEFAULT '' COMMENT '活动显示排序0=默认, 1=秒杀2=砍价3=拼团',
`sales_count` int DEFAULT '0' COMMENT '商品销量',
`virtual_sales_count` int DEFAULT '0' COMMENT '虚拟销量',
`browse_count` int DEFAULT '0' COMMENT '商品点击量',
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY("id")
) COMMENT '商品spu';
CREATE TABLE IF NOT EXISTS `product_category` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号',
`parent_id` bigint NOT NULL COMMENT '父分类编号',
`name` varchar(255) NOT NULL COMMENT '分类名称',
`pic_url` varchar(255) NOT NULL COMMENT '移动端分类图',
`big_pic_url` varchar(255) DEFAULT NULL COMMENT 'PC 端分类图',
`sort` int DEFAULT '0' COMMENT '分类排序',
`status` tinyint NOT NULL COMMENT '开启状态',
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY("id")
) COMMENT '商品分类';
CREATE TABLE IF NOT EXISTS `product_brand` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌编号',
`name` varchar(255) NOT NULL COMMENT '品牌名称',
`pic_url` varchar(255) NOT NULL COMMENT '品牌图片',
`sort` int DEFAULT '0' COMMENT '品牌排序',
`description` varchar(1024) DEFAULT NULL COMMENT '品牌描述',
`status` tinyint NOT NULL COMMENT '状态',
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY("id")
) COMMENT '商品品牌';
CREATE TABLE IF NOT EXISTS `product_property` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(64) DEFAULT NULL COMMENT '规格名称',
`status` tinyint DEFAULT NULL COMMENT '状态: 0 开启 1 禁用',
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
PRIMARY KEY("id")
) COMMENT '规格名称';
CREATE TABLE IF NOT EXISTS `product_property_value` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`property_id` bigint DEFAULT NULL COMMENT '规格键id',
`name` varchar(128) DEFAULT NULL COMMENT '规格值名字',
`status` tinyint DEFAULT NULL COMMENT '状态: 1 开启 2 禁用',
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
PRIMARY KEY("id")
) COMMENT '规格值';
DROP TABLE IF EXISTS `product_comment` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '评论编号,主键自增',
`user_id` bigint DEFAULT NULL COMMENT '评价人的用户编号关联 MemberUserDO 的 id 编号',
`user_nickname` varchar(255) DEFAULT NULL COMMENT '评价人名称',
`user_avatar` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '评价人头像',
`anonymous` bit(1) DEFAULT NULL COMMENT '是否匿名',
`order_id` bigint DEFAULT NULL COMMENT '交易订单编号关联 TradeOrderDO 的 id 编号',
`order_item_id` bigint DEFAULT NULL COMMENT '交易订单项编号关联 TradeOrderItemDO 的 id 编号',
`spu_id` bigint DEFAULT NULL COMMENT '商品 SPU 编号关联 ProductSpuDO 的 id',
`spu_name` varchar(255) DEFAULT NULL COMMENT '商品 SPU 名称',
`sku_id` bigint DEFAULT NULL COMMENT '商品 SKU 编号关联 ProductSkuDO 的 id 编号',
`visible` bit(1) DEFAULT NULL COMMENT '是否可见true:显示false:隐藏',
`scores` tinyint DEFAULT NULL COMMENT '评分星级1-5分',
`description_scores` tinyint DEFAULT NULL COMMENT '描述星级1-5 星',
`benefit_scores` tinyint DEFAULT NULL COMMENT '服务星级1-5 星',
`content` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '评论内容',
`pic_urls` varchar(4096) DEFAULT NULL COMMENT '评论图片地址数组',
`reply_status` bit(1) DEFAULT NULL COMMENT '商家是否回复',
`reply_user_id` bigint DEFAULT NULL COMMENT '回复管理员编号关联 AdminUserDO 的 id 编号',
`reply_content` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '商家回复内容',
`reply_time` datetime DEFAULT NULL COMMENT '商家回复时间',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 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 AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '商品评论';