tsurumure 1 сар өмнө
parent
commit
b762679b43

+ 1 - 1
db/__b2c_goods.sql

@@ -15,7 +15,7 @@ CREATE TABLE `b2c_goods` (
     `good_description` VARCHAR(200) COMMENT '商品描述',
     `good_content` TEXT COMMENT '商品内容',
     `good_thumb` VARCHAR(1000) DEFAULT NULL COMMENT '商品缩略图',
-    `good_images` TEXT DEFAULT NULL COMMENT '商品图片',
+    `good_images` TEXT DEFAULT NULL COMMENT '商品图片 (多图片以逗号间隔)',
     `meta_keyword` VARCHAR(100) COMMENT 'SEO-Keyword',
     `meta_description` VARCHAR(200) COMMENT 'SEO-Description',
     `status` TINYINT(1) DEFAULT '-1' COMMENT '商品状态 (-1下架, 1上架)',

+ 0 - 0
db/b2c_goods_category.sql → db/__b2c_goods_category.sql


+ 41 - 0
db/b2c_good.sql

@@ -0,0 +1,41 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2023/08/18 12:51:10
+*/
+
+DROP TABLE IF EXISTS `b2c_good`;
+CREATE TABLE `b2c_good` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
+    `uid` VARCHAR(36) NOT NULL UNIQUE COMMENT 'UID',
+    `category_id` BIGINT NOT NULL COMMENT '商品分类ID',
+    `brand_id` BIGINT COMMENT '商品品牌ID',
+    `unit_id` BIGINT COMMENT '商品单位ID',
+    `good_thumb` VARCHAR(1000) DEFAULT NULL COMMENT '商品缩略图',
+    `good_images` TEXT DEFAULT NULL COMMENT '商品图片 (多图片以逗号间隔)',
+    `is_top` TINYINT(1) DEFAULT '-1' COMMENT '是否置顶 (-1否, 1是)',
+    `status` TINYINT(1) DEFAULT '-1' COMMENT '商品状态 (-1下架, 1上架)',
+    `del_flag` TINYINT(1) DEFAULT '-1' COMMENT '删除标志 (-1未删除, 1删除)',
+    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    UNIQUE KEY (`uid`),
+    INDEX `idx_category_id` (`category_id`),
+    INDEX `idx_brand_id` (`brand_id`),
+    INDEX `idx_unit_id` (`unit_id`)
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
+
+INSERT INTO b2c_good(uid, category_id, brand_id, unit_id, status) VALUES
+    ('a1b2c3d4e1', 1, 1, 1, 1),
+    ('a1b2c3d4e2', 1, 1, 1, -1),
+    ('a1b2c3d4e3', 1, 1, 1, -1),
+    ('a1b2c3d4e4', 1, 1, 1, -1),
+    ('a1b2c3d4e5', 1, 1, 1, -1),
+    ('a1b2c3d4e6', 1, 1, 1, -1),
+    ('a1b2c3d4e7', 1, 1, 1, -1),
+    ('a1b2c3d4e8', 1, 1, 1, -1),
+    ('a1b2c3d4e9', 1, 1, 1, -1),
+    ('a1b2c3d4e0', 1, 1, 1, -1),
+    ('a1b2c3d410', 1, 1, 1, -1),
+    ('a1b2c3d411', 1, 1, 1, -1)
+;

+ 23 - 0
db/b2c_good_category.sql

@@ -0,0 +1,23 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2023/08/18 12:51:10
+*/
+
+DROP TABLE IF EXISTS `b2c_good_category`;
+CREATE TABLE `b2c_good_category` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
+    `parent_id` BIGINT COMMENT '父ID',
+    `sort` INT DEFAULT '1' COMMENT '排序',
+    `status` TINYINT(1) DEFAULT '1' COMMENT '商品分类状态 (-1禁用, 1启用)'
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='商品分类表';
+
+INSERT INTO b2c_good_category(parent_id, sort) VALUES
+    (-1, 5),
+    (-1, 4),
+    (-1, 3),
+    (-1, 2),
+    (-1, 1)
+;
+

+ 29 - 0
db/b2c_good_category_i18n.sql

@@ -0,0 +1,29 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2023/08/18 12:51:10
+*/
+
+DROP TABLE IF EXISTS `b2c_good_category_i18n`;
+CREATE TABLE `b2c_good_category_i18n` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
+    `good_category_id` BIGINT NOT NULL COMMENT '分类ID',
+    `language` VARCHAR(10) NOT NULL COMMENT '语种',
+    `category_name` VARCHAR(100) NOT NULL COMMENT '商品分类名称',
+    `category_description` VARCHAR(500) COMMENT '商品分类描述'
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='商品分类表';
+
+INSERT INTO b2c_good_category_i18n(good_category_id, language, category_name, category_description) VALUES
+    (1, 'zh', '电子产品', '手机、电脑、平板等电子设备'),
+    (1, 'en', 'Electronics', 'Mobile phones, computers, tablets and other electronic devices'),
+    (2, 'zh', '家具', '床、沙发、餐桌等家居用品'),
+    (2, 'en', 'Furniture', 'Beds, sofas, dining tables and other household items'),
+    (3, 'zh', '食品', '食品、零食、饮料等食品类产品'),
+    (3, 'en', 'Food', 'Food, snacks, beverages and other food products'),
+    (4, 'zh', '服装', '包括衣服、鞋子、配饰等服装类产品'),
+    (4, 'en', 'Apparel', 'Clothing, shoes, accessories and other apparel products'),
+    (5, 'zh', '美容', '化妆品、护肤品、美发用品等美容类产品'),
+    (5, 'en', 'Beauty', 'Cosmetics, skincare, hair care products and other beauty items')
+;
+

+ 46 - 0
db/b2c_good_i18n.sql

@@ -0,0 +1,46 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2023/08/18 12:51:10
+*/
+
+DROP TABLE IF EXISTS `b2c_good_i18n`;
+CREATE TABLE `b2c_good_i18n` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
+    `good_id` BIGINT NOT NULL COMMENT '商品ID',
+    `language` VARCHAR(10) NOT NULL COMMENT '语种',
+    `good_name` VARCHAR(20) NOT NULL COMMENT '商品名称',
+    `good_description` VARCHAR(200) COMMENT '商品描述',
+    `good_content` TEXT COMMENT '商品内容',
+    `meta_keyword` VARCHAR(100) COMMENT 'SEO-Keyword',
+    `meta_description` VARCHAR(200) COMMENT 'SEO-Description',
+    INDEX `idx_good_name` (`good_name`)
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='商品表 (翻译)';
+
+INSERT INTO b2c_good_i18n(good_id, language, good_name, good_description, good_content) VALUES
+    (1, 'zh', '测试商品-1', '测试商品描述描述-1', '测试商品详情内容内容内容内容-1'),
+    (1, 'en', 'Debug Good-1', 'Debug Good description-1', 'Debug Good content-1'),
+    (1, 'zh', '测试商品-2', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-2', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-3', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-3', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-4', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-4', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-5', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-5', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-6', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-6', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-7', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-7', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-8', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-8', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-9', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-9', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-10', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-10', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-11', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-11', 'Debug Good description', 'Debug Good content'),
+    (1, 'zh', '测试商品-12', '测试商品描述描述', '测试商品详情内容内容内容内容'),
+    (1, 'en', 'Debug Good-12', 'Debug Good description', 'Debug Good content')
+;

+ 0 - 41
db/b2c_goods.sql

@@ -1,41 +0,0 @@
-/**
-Source Server Version: 8.0.31
-Source Database: backendsys
-Date: 2023/08/18 12:51:10
-*/
-
-DROP TABLE IF EXISTS `b2c_goods`;
-CREATE TABLE `b2c_goods` (
-    PRIMARY KEY (`id`),
-    `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
-    `category_id` BIGINT NOT NULL COMMENT '商品分类ID',
-    `brand_id` BIGINT COMMENT '商品品牌ID',
-    `unit_id` BIGINT COMMENT '商品单位ID',
-    `good_name` VARCHAR(20) NOT NULL COMMENT '商品名称',
-    `good_description` VARCHAR(200) COMMENT '商品描述',
-    `good_content` TEXT COMMENT '商品内容',
-    `good_thumb` VARCHAR(1000) DEFAULT NULL COMMENT '商品缩略图',
-    `good_images` TEXT DEFAULT NULL COMMENT '商品图片',
-    `meta_keyword` VARCHAR(100) COMMENT 'SEO-Keyword',
-    `meta_description` VARCHAR(200) COMMENT 'SEO-Description',
-    `status` TINYINT(1) DEFAULT '-1' COMMENT '商品状态 (-1下架, 1上架)',
-    `del_flag` TINYINT(1) DEFAULT '-1' COMMENT '删除标志 (-1未删除, 1删除)',
-    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-    INDEX `idx_good_name` (`good_name`)
-) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
-
-INSERT INTO b2c_goods(category_id, brand_id, unit_id, good_name, good_description, good_content, status) VALUES
-    (1, 1, 1, '测试商品-1', '测试商品描述描述-1', '测试商品详情内容内容内容内容-1', 1),
-    (1, 1, 1, '测试商品-2', '测试商品描述描述-2', '测试商品详情内容内容内容内容-2', -1),
-    (1, 1, 1, '测试商品-3', '测试商品描述描述-3', '测试商品详情内容内容内容内容-3', -1),
-    (1, 1, 1, '测试商品-4', '测试商品描述描述-4', '测试商品详情内容内容内容内容-4', -1),
-    (1, 1, 1, '测试商品-5', '测试商品描述描述-5', '测试商品详情内容内容内容内容-5', -1),
-    (1, 1, 1, '测试商品-6', '测试商品描述描述-6', '测试商品详情内容内容内容内容-6', -1),
-    (1, 1, 1, '测试商品-7', '测试商品描述描述-7', '测试商品详情内容内容内容内容-7', -1),
-    (1, 1, 1, '测试商品-8', '测试商品描述描述-8', '测试商品详情内容内容内容内容-8', -1),
-    (1, 1, 1, '测试商品-9', '测试商品描述描述-9', '测试商品详情内容内容内容内容-9', -1),
-    (1, 1, 1, '测试商品-10', '测试商品描述描述-10', '测试商品详情内容内容内容内容-10', -1),
-    (1, 1, 1, '测试商品-11', '测试商品描述描述-11', '测试商品详情内容内容内容内容-11', -1),
-    (1, 1, 1, '测试商品-12', '测试商品描述描述-12', '测试商品详情内容内容内容内容-12', -1)
-;

+ 4 - 2
db/cms_article.sql

@@ -8,16 +8,18 @@ DROP TABLE IF EXISTS `cms_article`;
 CREATE TABLE `cms_article` (
     PRIMARY KEY (`id`),
     `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
+    `uid` VARCHAR(36) NOT NULL UNIQUE COMMENT 'UID',
     `user_id` BIGINT NOT NULL COMMENT '作者/用户ID',
     `category_id` BIGINT NOT NULL COMMENT '资讯分类ID',
-    `uid` VARCHAR(36) NOT NULL UNIQUE COMMENT 'UID',
     `thumb` VARCHAR(500) COMMENT '封面图',
     `is_top` TINYINT(1) DEFAULT '-1' COMMENT '是否置顶 (-1否, 1是)',
     `status` TINYINT(1) DEFAULT '1' COMMENT '资讯状态 (-1禁用, 1启用)',
     `del_flag` TINYINT(1) DEFAULT '-1' COMMENT '删除标志 (-1未删除, 1删除)',
     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
     `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-    INDEX `idx_user_id` (`user_id`)
+    UNIQUE KEY (`uid`),
+    INDEX `idx_user_id` (`user_id`),
+    INDEX `idx_category_id` (`category_id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='资讯表';
 
 INSERT INTO cms_article(user_id, category_id, uid, is_top) VALUES

+ 65 - 65
src/main/java/com/backendsys/controller/B2c/B2cGoodController.java

@@ -1,65 +1,65 @@
-package com.backendsys.controller.B2c;
-
-import com.backendsys.aspect.QueryNullCheck;
-import com.backendsys.aspect.QueryNullCheckAspect;
-import com.backendsys.entity.B2c.B2cGoodDTO;
-import com.backendsys.entity.PageDTO;
-import com.backendsys.modules.common.aspect.AppUserLogin;
-import com.backendsys.service.B2c.B2cGoodService;
-import com.backendsys.utils.response.Result;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 商品
- */
-@Validated
-@RestController
-public class B2cGoodController {
-
-    @Autowired
-    private B2cGoodService b2cGoodService;
-
-    @PreAuthorize("@sr.hasPermission('11.1')")
-    @GetMapping("/api/b2c/good/getGood")
-    public Result getGood(@Validated PageDTO pageDTO, @Validated B2cGoodDTO b2cGoodDTO) {
-        return Result.success(b2cGoodService.queryGoodList(pageDTO.getPage_num(), pageDTO.getPage_size(), b2cGoodDTO));
-    }
-
-//    @PreAuthorize("@ss.isMember")
-    @AppUserLogin
-    @GetMapping("/api/front/b2c/good/getGood")
-    public Result getFrontGood(@Validated PageDTO pageDTO, @Validated B2cGoodDTO b2cGoodDTO) {
-        return Result.success(b2cGoodService.queryGoodList(pageDTO.getPage_num(), pageDTO.getPage_size(), b2cGoodDTO));
-    }
-    // 现有一个接口路径:/api/b2c/good/getGood,是用于后台系统获取商品列表的,想另外做一个用于前台H5或小程序调用的接口,应该怎么命名比较优雅
-
-    @PreAuthorize("@sr.hasPermission('11.1.1')")
-    @QueryNullCheck(serviceClass = B2cGoodService.class, serviceMethod = "queryGoodDetail", argField = "good_id", message = "商品不存在")
-    @GetMapping("/api/b2c/good/getGoodDetail")
-    public Result getGoodDetail(@Validated(B2cGoodDTO.Detail.class) B2cGoodDTO b2cGoodDTO) {
-        return Result.success(QueryNullCheckAspect.getQueryResult());
-    }
-
-    @PreAuthorize("@sr.hasPermission('11.1.2')")
-    @PostMapping("/api/b2c/good/createGood")
-    public Result createGood(@Validated(B2cGoodDTO.Create.class) @RequestBody B2cGoodDTO b2cGoodDTO) {
-        return Result.success(b2cGoodService.insertGood(b2cGoodDTO), "创建成功");
-    }
-
-    @PreAuthorize("@sr.hasPermission('11.1.3')")
-    @QueryNullCheck(serviceClass = B2cGoodService.class, serviceMethod = "queryGoodDetail", argField = "good_id", message = "商品不存在")
-    @PutMapping("/api/b2c/good/updateGood")
-    public Result updateGood(@Validated(B2cGoodDTO.Update.class) @RequestBody B2cGoodDTO b2cGoodDTO) {
-        return Result.success(b2cGoodService.updateGood(b2cGoodDTO), "更新成功");
-    }
-
-    @PreAuthorize("@sr.hasPermission('11.1.4')")
-    @QueryNullCheck(serviceClass = B2cGoodService.class, serviceMethod = "queryGoodDetail", argField = "good_id", message = "商品不存在")
-    @DeleteMapping("/api/b2c/good/deleteGood")
-    public Result deleteGood(@Validated(B2cGoodDTO.Delete.class) @RequestBody B2cGoodDTO b2cGoodDTO) {
-        return Result.success(b2cGoodService.deleteGood(b2cGoodDTO), "删除成功");
-    }
-}
+//package com.backendsys.controller.B2c;
+//
+//import com.backendsys.aspect.QueryNullCheck;
+//import com.backendsys.aspect.QueryNullCheckAspect;
+//import com.backendsys.entity.B2c.B2cGoodDTO;
+//import com.backendsys.entity.PageDTO;
+//import com.backendsys.modules.common.aspect.AppUserLogin;
+//import com.backendsys.service.B2c.B2cGoodService;
+//import com.backendsys.utils.response.Result;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.security.access.prepost.PreAuthorize;
+//import org.springframework.validation.annotation.Validated;
+//import org.springframework.web.bind.annotation.*;
+//
+///**
+// * 商品
+// */
+//@Validated
+//@RestController
+//public class GoodController {
+//
+//    @Autowired
+//    private B2cGoodService b2cGoodService;
+//
+//    @PreAuthorize("@sr.hasPermission('11.1')")
+//    @GetMapping("/api/b2c/good/getGood")
+//    public Result getGood(@Validated PageDTO pageDTO, @Validated B2cGoodDTO b2cGoodDTO) {
+//        return Result.success(b2cGoodService.queryGoodList(pageDTO.getPage_num(), pageDTO.getPage_size(), b2cGoodDTO));
+//    }
+//
+////    @PreAuthorize("@ss.isMember")
+//    @AppUserLogin
+//    @GetMapping("/api/front/b2c/good/getGood")
+//    public Result getFrontGood(@Validated PageDTO pageDTO, @Validated B2cGoodDTO b2cGoodDTO) {
+//        return Result.success(b2cGoodService.queryGoodList(pageDTO.getPage_num(), pageDTO.getPage_size(), b2cGoodDTO));
+//    }
+//    // 现有一个接口路径:/api/b2c/good/getGood,是用于后台系统获取商品列表的,想另外做一个用于前台H5或小程序调用的接口,应该怎么命名比较优雅
+//
+//    @PreAuthorize("@sr.hasPermission('11.1.1')")
+//    @QueryNullCheck(serviceClass = B2cGoodService.class, serviceMethod = "queryGoodDetail", argField = "good_id", message = "商品不存在")
+//    @GetMapping("/api/b2c/good/getGoodDetail")
+//    public Result getGoodDetail(@Validated(B2cGoodDTO.Detail.class) B2cGoodDTO b2cGoodDTO) {
+//        return Result.success(QueryNullCheckAspect.getQueryResult());
+//    }
+//
+//    @PreAuthorize("@sr.hasPermission('11.1.2')")
+//    @PostMapping("/api/b2c/good/createGood")
+//    public Result createGood(@Validated(B2cGoodDTO.Create.class) @RequestBody B2cGoodDTO b2cGoodDTO) {
+//        return Result.success(b2cGoodService.insertGood(b2cGoodDTO), "创建成功");
+//    }
+//
+//    @PreAuthorize("@sr.hasPermission('11.1.3')")
+//    @QueryNullCheck(serviceClass = B2cGoodService.class, serviceMethod = "queryGoodDetail", argField = "good_id", message = "商品不存在")
+//    @PutMapping("/api/b2c/good/updateGood")
+//    public Result updateGood(@Validated(B2cGoodDTO.Update.class) @RequestBody B2cGoodDTO b2cGoodDTO) {
+//        return Result.success(b2cGoodService.updateGood(b2cGoodDTO), "更新成功");
+//    }
+//
+//    @PreAuthorize("@sr.hasPermission('11.1.4')")
+//    @QueryNullCheck(serviceClass = B2cGoodService.class, serviceMethod = "queryGoodDetail", argField = "good_id", message = "商品不存在")
+//    @DeleteMapping("/api/b2c/good/deleteGood")
+//    public Result deleteGood(@Validated(B2cGoodDTO.Delete.class) @RequestBody B2cGoodDTO b2cGoodDTO) {
+//        return Result.success(b2cGoodService.deleteGood(b2cGoodDTO), "删除成功");
+//    }
+//}

+ 29 - 0
src/main/java/com/backendsys/modules/b2c/good/controller/GoodController.java

@@ -0,0 +1,29 @@
+package com.backendsys.modules.b2c.good.controller;
+
+import com.backendsys.modules.b2c.good.entity.Good;
+import com.backendsys.modules.b2c.good.service.GoodService;
+import com.backendsys.modules.common.utils.Result;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Validated
+@RestController
+@Tag(name = "商品管理")
+public class GoodController {
+
+    @Autowired
+    private GoodService goodService;
+
+    @Operation(summary = "获取商品列表")
+    @PreAuthorize("@sr.hasPermission('11.1')")
+    @GetMapping("/api/b2c/good/getGoodList")
+    public Result getGood(@Validated Good good) {
+        return Result.success().put("data", goodService.selectGoodList(good));
+    }
+
+}

+ 16 - 0
src/main/java/com/backendsys/modules/b2c/good/dao/GoodDao.java

@@ -0,0 +1,16 @@
+package com.backendsys.modules.b2c.good.dao;
+
+import com.backendsys.modules.b2c.good.entity.Good;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface GoodDao extends BaseMapper<Good> {
+
+    // 获取商品列表
+    List<Map<String, Object>> selectGoodList(Good good);
+
+}

+ 96 - 0
src/main/java/com/backendsys/modules/b2c/good/entity/Good.java

@@ -0,0 +1,96 @@
+package com.backendsys.modules.b2c.good.entity;
+
+import com.backendsys.config.Mybatis.handler.timezone.LocalDateTimeAdapter;
+import com.backendsys.entity.B2c.B2cGoodDTO;
+import com.backendsys.entity.validator.RangeArray;
+import com.backendsys.modules.cms.article.entity.Article;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.google.gson.annotations.JsonAdapter;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("b2c_good")
+public class Good {
+
+    public static interface Detail{}
+    public static interface DetailByUid{}
+    public static interface Create{}
+    public static interface Update{}
+    public static interface Delete{}
+    public static interface DeleteBatch{}
+
+    @TableField(exist = false)
+    private String lang;
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    @TableField("id")
+    @NotNull(message="good_id 不能为空", groups = { Detail.class, Update.class, Delete.class })
+    private Long good_id;
+
+    @NotEmpty(message="uid 不能为空", groups = { DetailByUid.class })
+    private String uid;
+
+    @NotNull(message = "商品分类ID不能为空", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private Long category_id;
+    private String category_name;
+
+    private Long brand_id;
+    private String brand_name;
+    private Long unit_id;
+    private String unit_name;
+
+    @NotBlank(message = "商品名称不能为空", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    @Size(max = 50, message = "商品名称长度不超过 {max} 字符", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private String good_name;
+
+    @Size(max = 200, message = "商品描述长度不超过 {max} 字符", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private String good_description;
+
+    @Size(max = 20000, message = "商品内容长度不超过 {max} 字符", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private String good_content;
+
+    @Size(max = 2000, message = "商品缩略图地址长度不超过 {max} 字符", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private String good_thumb;
+
+    @Size(max = 20000, message = "商品图片地址长度不超过 {max} 字符", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private String good_images;
+
+    @Size(max = 100, message = "关键词长度不超过 {max} 字符", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private String meta_keyword;
+    @Size(max = 200, message = "关键词描述长度不超过 {max} 字符", groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private String meta_description;
+
+    @RangeArray(message="商品状态取值有误,范围应是(-1禁用, 1启用)", value = {"-1", "1"}, groups = { B2cGoodDTO.Create.class, B2cGoodDTO.Update.class })
+    private Integer status;
+
+    private Integer del_flag;
+
+    @TableField(exist = false)
+    private String create_time_begin;
+    @TableField(exist = false)
+    private String create_time_end;
+
+    @JsonAdapter(LocalDateTimeAdapter.class)
+    private LocalDateTime create_time;
+
+    @JsonAdapter(LocalDateTimeAdapter.class)
+    private LocalDateTime update_time;
+
+    @TableField(value = "create_time")
+    private String create_time_utc;
+
+    @TableField(value = "update_time")
+    private String update_time_utc;
+
+}

+ 11 - 0
src/main/java/com/backendsys/modules/b2c/good/service/GoodService.java

@@ -0,0 +1,11 @@
+package com.backendsys.modules.b2c.good.service;
+
+import com.backendsys.modules.b2c.good.entity.Good;
+import com.backendsys.utils.response.PageEntity;
+
+public interface GoodService {
+
+    // 获取商品列表
+    PageEntity selectGoodList(Good good);
+
+}

+ 31 - 0
src/main/java/com/backendsys/modules/b2c/good/service/impl/GoodServiceImpl.java

@@ -0,0 +1,31 @@
+package com.backendsys.modules.b2c.good.service.impl;
+
+import com.backendsys.modules.b2c.good.dao.GoodDao;
+import com.backendsys.modules.b2c.good.entity.Good;
+import com.backendsys.modules.b2c.good.service.GoodService;
+import com.backendsys.utils.response.PageEntity;
+import com.backendsys.utils.response.PageInfoResult;
+import com.backendsys.utils.v2.PageUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class GoodServiceImpl implements GoodService {
+
+    @Autowired
+    private GoodDao goodDao;
+
+    /**
+     * 获取商品列表
+     */
+    @Override
+    public PageEntity selectGoodList(Good good) {
+        PageUtils.startPage();  // 分页
+        List<Map<String, Object>> list = goodDao.selectGoodList(good);
+        return new PageInfoResult(list).toEntity();
+    }
+
+}

+ 5 - 0
src/main/java/com/backendsys/modules/cms/article/entity/Article.java

@@ -65,6 +65,11 @@ public class Article {
     private Integer is_top;
 
 
+    @TableField(exist = false)
+    private String create_time_begin;
+    @TableField(exist = false)
+    private String create_time_end;
+
     @JsonAdapter(LocalDateTimeAdapter.class)
     private LocalDateTime create_time;
 

+ 204 - 0
src/main/resources/mapper/b2c/good/GoodDao.xml

@@ -0,0 +1,204 @@
+<?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.backendsys.modules.b2c.good.dao.GoodDao">
+
+    <sql id="includeGood">
+        g.id id,
+        g.id good_id,
+        g.uid uid,
+        gc.id category_id,
+        gc.category_name category_name,
+        COALESCE(g.brand_id, -1) brand_id,
+        COALESCE(g.unit_id, -1) unit_id,
+        COALESCE(g.good_thumb, '') good_thumb,
+        COALESCE(g.good_images, '') good_images,
+        gt.good_name good_name,
+        COALESCE(gt.good_description, '') good_description,
+        g.status status,
+        g.is_top is_top,
+        g.create_time create_time,
+        g.update_time update_time
+    </sql>
+
+    <sql id="includeGoodDetail">
+        g.id id,
+        g.id good_id,
+        g.uid uid,
+        gc.id category_id,
+        gc.category_name category_name,
+        COALESCE(g.brand_id, -1) brand_id,
+        COALESCE(g.unit_id, -1) unit_id,
+        COALESCE(g.good_thumb, '') good_thumb,
+        COALESCE(g.good_images, '') good_images,
+        g.status status,
+        g.is_top is_top,
+        g.create_time create_time,
+        g.update_time update_time
+    </sql>
+
+    <sql id="includeGoodTranslation">
+        id,
+        good_id,
+        language,
+        good_name,
+        good_description,
+        good_content,
+        COALESCE(meta_keyword, '') meta_keyword,
+        COALESCE(meta_description, '') meta_description
+    </sql>
+    <sql id="leftJoinCategory">
+        LEFT JOIN b2c_good_category_i18n gc ON gc.good_category_id = g.category_id AND gc.language = #{lang}
+    </sql>
+    <sql id="leftJoinTranslations">
+        LEFT JOIN b2c_good_i18n gt ON g.id = gt.good_id
+    </sql>
+
+    <sql id="includeGoodDetailFull">
+        g.id id,
+        g.id good_id,
+        gt.language,
+        g.uid uid,
+
+        gc.id category_id,
+        gc.category_name category_name,
+        COALESCE(g.brand_id, -1) brand_id,
+        COALESCE(g.unit_id, -1) unit_id,
+        COALESCE(g.good_thumb, '') good_thumb,
+        COALESCE(g.good_images, '') good_images,
+
+        gt.good_name good_name,
+        COALESCE(gt.good_description, '') good_description,
+        COALESCE(gt.good_content, '') good_content,
+
+        g.status status,
+        g.is_top is_top,
+        g.create_time create_time,
+        g.update_time update_time
+    </sql>
+
+    <resultMap id="resultMapGood" type="java.util.LinkedHashMap">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="good_id" column="good_id" javaType="java.lang.Long" />
+        <result property="uid" column="uid" />
+        <result property="category_id" column="category_id" javaType="java.lang.Long" />
+        <result property="category_name" column="category_name" />
+        <result property="brand_id" column="brand_id" javaType="java.lang.Long" />
+        <result property="unit_id" column="unit_id" javaType="java.lang.Long" />
+        <result property="good_thumb" column="good_thumb" />
+        <result property="good_images" column="good_images" />
+        <result property="good_name" column="good_name" />
+        <result property="good_description" column="good_description" />
+        <result property="status" column="status" javaType="java.lang.Integer" />
+        <result property="is_top" column="is_top" javaType="java.lang.Integer" />
+        <result property="create_time" column="create_time" />
+        <result property="update_time" column="update_time" />
+    </resultMap>
+
+    <resultMap id="resultMapGoodDetail" type="java.util.LinkedHashMap">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="good_id" column="good_id" javaType="java.lang.Long" />
+        <result property="uid" column="uid" />
+        <result property="category_id" column="category_id" javaType="java.lang.Long" />
+        <result property="category_name" column="category_name" />
+        <result property="brand_id" column="brand_id" javaType="java.lang.Long" />
+        <result property="unit_id" column="unit_id" javaType="java.lang.Long" />
+        <result property="good_thumb" column="good_thumb" />
+        <result property="good_images" column="good_images" />
+        <result property="status" column="status" javaType="java.lang.Integer" />
+        <result property="is_top" column="is_top" javaType="java.lang.Integer" />
+        <result property="create_time" column="create_time" />
+        <result property="update_time" column="update_time" />
+        <collection property="translations" javaType="java.util.List"
+            select="queryTranslationsById" column="id">
+            <id property="id" column="id" />
+            <result property="good_name" column="good_name" />
+            <result property="good_description" column="good_description" />
+            <result property="good_content" column="good_content" />
+            <result property="meta_keyword" column="meta_keyword" />
+            <result property="meta_description" column="meta_description" />
+        </collection>
+    </resultMap>
+
+    <resultMap id="resultMapGoodDetailFull" type="java.util.LinkedHashMap">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="good_id" column="good_id" javaType="java.lang.Long" />
+        <result property="uid" column="uid" />
+        <result property="language" column="language" />
+        <result property="category_id" column="category_id" javaType="java.lang.Long" />
+        <result property="category_name" column="category_name" />
+        <result property="brand_id" column="brand_id" javaType="java.lang.Long" />
+        <result property="unit_id" column="unit_id" javaType="java.lang.Long" />
+        <result property="good_thumb" column="good_thumb" />
+        <result property="good_images" column="good_images" />
+        <result property="good_name" column="good_name" />
+        <result property="good_description" column="good_description" />
+        <result property="good_content" column="good_content" />
+        <result property="meta_keyword" column="meta_keyword" />
+        <result property="meta_description" column="meta_description" />
+        <result property="status" column="status" javaType="java.lang.Integer" />
+        <result property="is_top" column="is_top" javaType="java.lang.Integer" />
+        <result property="create_time" column="create_time" />
+        <result property="update_time" column="update_time" />
+    </resultMap>
+
+    <!-- 查 列表 -->
+    <select id="selectGoodList" resultMap="resultMapGood">
+        SELECT <include refid="includeGood" /> FROM b2c_good g
+        <include refid="leftJoinCategory" />
+        <include refid="leftJoinTranslations" />
+        <where>
+            gt.language = #{lang}
+            <if test="uid != null and uid != ''">
+                AND g.uid = #{uid}
+            </if>
+            <if test="category_id != null and category_id != ''">
+                AND g.category_id = #{category_id}
+            </if>
+            <if test="good_name != null and good_name != ''">
+                AND gt.good_name LIKE CONCAT('%', #{good_name}, '%')
+            </if>
+            <if test="status != null and status != ''">
+                AND g.status = #{status}
+            </if>
+            <if test="create_time_begin != null and create_time_begin != '' and create_time_end != null and create_time_end != ''">
+                AND g.create_time BETWEEN #{create_time_begin} AND #{create_time_end}
+            </if>
+        </where>
+        ORDER BY g.is_top = 1 DESC, g.create_time DESC
+    </select>
+
+    <!-- 查 详情 -->
+    <select id="selectGoodDetail" resultMap="resultMapGoodDetail">
+        SELECT <include refid="includeGoodDetail" />
+        FROM b2c_good g
+        <include refid="leftJoinCategory" />
+        <where>
+            <if test="uid != null and uid != ''">
+                AND g.uid = #{uid}
+            </if>
+            <if test="good_id != null and good_id != ''">
+                AND g.id = #{good_id}
+            </if>
+        </where>
+    </select>
+
+    <!-- 查 详情 完整 -->
+    <select id="selectGoodDetailFull" resultMap="resultMapGoodDetailFull">
+        SELECT <include refid="includeGoodDetailFull" />
+        FROM b2c_good g
+        <include refid="leftJoinCategory" />
+        <include refid="leftJoinTranslations" />
+        WHERE
+            gt.language = #{lang}
+            AND g.uid = #{uid}
+            AND g.status = #{status}
+    </select>
+
+    <!-- 查 翻译详情 (子查询) -->
+    <select id="queryTranslationsById" resultType="java.util.LinkedHashMap">
+        SELECT <include refid="includeGoodTranslation" />
+        FROM b2c_good_i18n
+        WHERE good_id = #{id}
+    </select>
+
+</mapper>

+ 4 - 14
src/main/resources/mapper/cms/article/ArticleDao.xml

@@ -9,8 +9,8 @@
         COALESCE(a.thumb, '') thumb,
         uf.user_id user_id,
         COALESCE(uf.nickname, '') user_nickname,
-        COALESCE(ac.id, -1) category_id,
-        COALESCE(ac.category_name, '') category_name,
+        ac.id category_id,
+        ac.category_name category_name,
         at.title title,
         COALESCE(at.description, '') description,
         a.status status,
@@ -170,8 +170,8 @@
             <if test="status != null and status != ''">
                 AND a.status = #{status}
             </if>
-            <if test="create_time != null and create_time != ''">
-                AND a.create_time >= #{create_time}
+            <if test="create_time_begin != null and create_time_begin != '' and create_time_end != null and create_time_end != ''">
+                AND a.create_time BETWEEN #{create_time_begin} AND #{create_time_end}
             </if>
         </where>
         ORDER BY a.is_top = 1 DESC, a.create_time DESC
@@ -213,14 +213,4 @@
         WHERE article_id = #{id}
     </select>
 
-    <!-- 查 详情 (公共) (带翻译 Object) (关联查询) -->
-<!--    <select id="queryArticleDetailPublic" resultMap="resultMapArticle">-->
-<!--        SELECT <include refid="includeArticle" />, content-->
-<!--        FROM cms_article a-->
-<!--        <include refid="leftJoinCategory" />-->
-<!--        <include refid="leftJoinUser" />-->
-<!--        <include refid="leftJoinTranslations" />-->
-<!--        WHERE a.uid = #{uid} AND at.language = #{lang}-->
-<!--    </select>-->
-
 </mapper>