page = categoryApplicationService.getCategoryAll();
+ return ResponseDTO.ok(page);
+ }
+}
+
diff --git a/agileboot-admin/src/main/java/com/agileboot/admin/controller/shop/ShopGoodsController.java b/agileboot-admin/src/main/java/com/agileboot/admin/controller/shop/ShopGoodsController.java
index 6906d97..b302885 100644
--- a/agileboot-admin/src/main/java/com/agileboot/admin/controller/shop/ShopGoodsController.java
+++ b/agileboot-admin/src/main/java/com/agileboot/admin/controller/shop/ShopGoodsController.java
@@ -1,19 +1,33 @@
package com.agileboot.admin.controller.shop;
+import com.agileboot.admin.customize.aop.accessLog.AccessLog;
import com.agileboot.common.core.dto.ResponseDTO;
import com.agileboot.common.core.page.PageDTO;
+import com.agileboot.common.enums.common.BusinessTypeEnum;
+import com.agileboot.domain.common.command.BulkOperationCommand;
import com.agileboot.domain.shop.goods.GoodsApplicationService;
import com.agileboot.domain.shop.goods.db.SearchGoodsDO;
import com.agileboot.domain.shop.goods.dto.ShopGoodsDTO;
import com.agileboot.domain.shop.goods.query.SearchShopGoodsQuery;
import io.swagger.v3.oas.annotations.Operation;
+import java.util.List;
import lombok.RequiredArgsConstructor;
+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 com.agileboot.common.core.base.BaseController;
+import com.agileboot.domain.shop.goods.command.AddGoodsCommand;
+import com.agileboot.domain.shop.goods.command.UpdateGoodsCommand;
+import javax.validation.constraints.NotNull;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
/**
*
@@ -26,6 +40,7 @@ import com.agileboot.common.core.base.BaseController;
@RestController
@RequestMapping("/shop/goods")
@RequiredArgsConstructor
+@Validated
public class ShopGoodsController extends BaseController {
private final GoodsApplicationService goodsApplicationService;
@@ -39,5 +54,34 @@ public class ShopGoodsController extends BaseController {
PageDTO page = goodsApplicationService.getGoodsList(query);
return ResponseDTO.ok(page);
}
+
+ @Operation(summary = "新增商品")
+// @PreAuthorize("@permission.has('shop:goods:add')")
+ @AccessLog(title = "商品管理", businessType = BusinessTypeEnum.ADD)
+ @PostMapping
+ public ResponseDTO add(@Validated @RequestBody AddGoodsCommand command) {
+ goodsApplicationService.addGoods(command);
+ return ResponseDTO.ok();
+ }
+
+ @Operation(summary = "删除商品")
+// @PreAuthorize("@permission.has('shop:goods:remove')")
+ @AccessLog(title = "商品管理", businessType = BusinessTypeEnum.DELETE)
+ @DeleteMapping("/{goodsIds}")
+ public ResponseDTO remove(@PathVariable @NotNull List goodsIds) {
+ BulkOperationCommand bulkDeleteCommand = new BulkOperationCommand<>(goodsIds);
+ goodsApplicationService.deleteGoods(bulkDeleteCommand);
+ return ResponseDTO.ok();
+ }
+
+ @Operation(summary = "修改商品")
+// @PreAuthorize("@permission.has('shop:goods:edit')")
+ @AccessLog(title = "商品管理", businessType = BusinessTypeEnum.MODIFY)
+ @PutMapping("/{goodsId}")
+ public ResponseDTO edit(@PathVariable Long goodsId, @Validated @RequestBody UpdateGoodsCommand command) {
+ command.setGoodsId(goodsId);
+ goodsApplicationService.updateGoods(command);
+ return ResponseDTO.ok();
+ }
}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/CategoryApplicationService.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/CategoryApplicationService.java
new file mode 100644
index 0000000..d8d3bc2
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/CategoryApplicationService.java
@@ -0,0 +1,34 @@
+package com.agileboot.domain.shop.category;
+
+import com.agileboot.common.core.page.PageDTO;
+import com.agileboot.domain.shop.category.db.ShopCategoryEntity;
+import com.agileboot.domain.shop.category.db.ShopCategoryService;
+import com.agileboot.domain.shop.category.dto.ShopCategoryDTO;
+import com.agileboot.domain.shop.category.query.SearchShopCategoryQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import java.util.List;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class CategoryApplicationService {
+ private final ShopCategoryService shopCategoryService;
+
+ public PageDTO getCategoryList(SearchShopCategoryQuery query) {
+ Page categoryPage = shopCategoryService.getCategoryList(query);
+ List dtoList = categoryPage.getRecords().stream()
+ .map(ShopCategoryDTO::new)
+ .collect(Collectors.toList());
+ return new PageDTO<>(dtoList, categoryPage.getTotal());
+ }
+
+
+ public List getCategoryAll() {
+ return shopCategoryService.getCategoryAll().stream()
+ .map(ShopCategoryDTO::new)
+ .collect(Collectors.toList());
+ }
+
+}
\ No newline at end of file
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryEntity.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryEntity.java
new file mode 100644
index 0000000..634ddc8
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryEntity.java
@@ -0,0 +1,52 @@
+package com.agileboot.domain.shop.category.db;
+
+import com.agileboot.common.core.base.BaseEntity;
+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 java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 商品分类表
+ *
+ *
+ * @author valarchie
+ * @since 2025-03-04
+ */
+@Getter
+@Setter
+@TableName("shop_category")
+@ApiModel(value = "ShopCategoryEntity对象", description = "商品分类表")
+public class ShopCategoryEntity extends BaseEntity {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("分类唯一ID")
+ @TableId(value = "category_id", type = IdType.AUTO)
+ private Long categoryId;
+
+ @ApiModelProperty("分类名称")
+ @TableField("category_name")
+ private String categoryName;
+
+ @ApiModelProperty("排序权重")
+ @TableField("sort")
+ private Integer sort;
+
+ @ApiModelProperty("分类描述")
+ @TableField("description")
+ private String description;
+
+
+ @Override
+ public Serializable pkVal() {
+ return this.categoryId;
+ }
+
+}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryMapper.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryMapper.java
new file mode 100644
index 0000000..72fb150
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryMapper.java
@@ -0,0 +1,43 @@
+package com.agileboot.domain.shop.category.db;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+/**
+ *
+ * 商品分类表 Mapper 接口
+ *
+ *
+ * @author valarchie
+ * @since 2025-03-04
+ */
+public interface ShopCategoryMapper extends BaseMapper {
+ /**
+ * 根据条件分页查询分类列表
+ * @param page 分页对象
+ * @param queryWrapper 查询条件
+ * @return 分类分页列表
+ */
+ @Select("SELECT category_id, category_name, sort, description " +
+ "FROM shop_category " +
+ "${ew.customSqlSegment}")
+ Page getCategoryList(
+ Page page,
+ @Param(Constants.WRAPPER) Wrapper queryWrapper
+ );
+
+ /**
+ * 查询所有分类(未删除的)
+ * @return 分类列表
+ */
+ @Select("SELECT * " +
+ "FROM shop_category " +
+ "WHERE deleted = 0 " +
+ "ORDER BY sort ASC")
+ List selectAll();
+}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryService.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryService.java
new file mode 100644
index 0000000..ae62118
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryService.java
@@ -0,0 +1,20 @@
+package com.agileboot.domain.shop.category.db;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.agileboot.common.core.page.AbstractPageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import java.util.List;
+
+/**
+ *
+ * 商品分类表 服务类
+ *
+ *
+ * @author valarchie
+ * @since 2025-03-04
+ */
+public interface ShopCategoryService extends IService {
+ Page getCategoryList(AbstractPageQuery query);
+
+ List getCategoryAll();
+}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryServiceImpl.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryServiceImpl.java
new file mode 100644
index 0000000..f93ccdb
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/db/ShopCategoryServiceImpl.java
@@ -0,0 +1,28 @@
+package com.agileboot.domain.shop.category.db;
+
+import com.agileboot.common.core.page.AbstractPageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import java.util.List;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 商品分类表 服务实现类
+ *
+ *
+ * @author valarchie
+ * @since 2025-03-04
+ */
+@Service
+public class ShopCategoryServiceImpl extends ServiceImpl implements ShopCategoryService {
+ @Override
+ public Page getCategoryList(AbstractPageQuery query) {
+ return baseMapper.selectPage(query.toPage(), query.toQueryWrapper());
+ }
+
+ @Override
+ public List getCategoryAll() {
+ return baseMapper.selectAll();
+ }
+}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/dto/ShopCategoryDTO.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/dto/ShopCategoryDTO.java
new file mode 100644
index 0000000..c7b0536
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/dto/ShopCategoryDTO.java
@@ -0,0 +1,48 @@
+package com.agileboot.domain.shop.category.dto;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.agileboot.common.annotation.ExcelColumn;
+import com.agileboot.common.annotation.ExcelSheet;
+import com.agileboot.domain.shop.category.db.ShopCategoryEntity;
+import java.util.Date;
+import lombok.Data;
+
+@ExcelSheet(name = "商品分类列表")
+@Data
+public class ShopCategoryDTO {
+
+ public ShopCategoryDTO(ShopCategoryEntity entity) {
+ if (entity != null) {
+ BeanUtil.copyProperties(entity, this);
+
+ // 如果需要关联查询,可参考以下方式(根据实际需求启用)
+ /*
+ SysUserEntity creator = CacheCenter.userCache.getObjectById(entity.getCreatorId());
+ if (creator != null) {
+ this.creatorName = creator.getUsername();
+ }
+ */
+ }
+ }
+
+ @ExcelColumn(name = "分类ID")
+ private Long categoryId;
+
+ @ExcelColumn(name = "分类名称")
+ private String categoryName;
+
+ @ExcelColumn(name = "排序权重")
+ private Integer sort;
+
+ @ExcelColumn(name = "分类描述")
+ private String description;
+
+ @ExcelColumn(name = "创建者ID")
+ private Long creatorId;
+
+ @ExcelColumn(name = "创建者")
+ private String creatorName;
+
+ @ExcelColumn(name = "创建时间")
+ private Date createTime;
+}
\ No newline at end of file
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/query/SearchShopCategoryQuery.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/query/SearchShopCategoryQuery.java
new file mode 100644
index 0000000..2f925ff
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/category/query/SearchShopCategoryQuery.java
@@ -0,0 +1,28 @@
+package com.agileboot.domain.shop.category.query;
+
+import cn.hutool.core.util.StrUtil;
+import com.agileboot.common.core.page.AbstractPageQuery;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class SearchShopCategoryQuery extends AbstractPageQuery {
+
+ protected String categoryName;
+
+ @Override
+ public QueryWrapper addQueryCondition() {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+
+ queryWrapper
+ .like(StrUtil.isNotEmpty(categoryName), "category_name", categoryName)
+ .eq("deleted", 0)
+ .orderByAsc("sort");
+
+ this.timeRangeColumn = "create_time";
+
+ return queryWrapper;
+ }
+}
\ No newline at end of file
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/GoodsApplicationService.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/GoodsApplicationService.java
index b82e1d2..2d0501a 100644
--- a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/GoodsApplicationService.java
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/GoodsApplicationService.java
@@ -1,9 +1,14 @@
package com.agileboot.domain.shop.goods;
import com.agileboot.common.core.page.PageDTO;
+import com.agileboot.domain.common.command.BulkOperationCommand;
+import com.agileboot.domain.shop.goods.command.AddGoodsCommand;
+import com.agileboot.domain.shop.goods.command.UpdateGoodsCommand;
import com.agileboot.domain.shop.goods.db.SearchGoodsDO;
import com.agileboot.domain.shop.goods.db.ShopGoodsService;
import com.agileboot.domain.shop.goods.dto.ShopGoodsDTO;
+import com.agileboot.domain.shop.goods.model.GoodsModel;
+import com.agileboot.domain.shop.goods.model.GoodsModelFactory;
import com.agileboot.domain.shop.goods.query.SearchShopGoodsQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;
@@ -15,10 +20,38 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class GoodsApplicationService {
private final ShopGoodsService shopGoodsService;
+ private final GoodsModelFactory goodsModelFactory;
public PageDTO getGoodsList(SearchShopGoodsQuery query) {
Page goodsPage = shopGoodsService.getGoodsList(query);
List goodsDTOList = goodsPage.getRecords().stream().map(ShopGoodsDTO::new).collect(Collectors.toList());
return new PageDTO<>(goodsDTOList, goodsPage.getTotal());
}
+
+ public void addGoods(AddGoodsCommand command) {
+ GoodsModel model = goodsModelFactory.create();
+ model.loadAddGoodsCommand(command);
+
+/* model.checkGoodsNameUnique();
+ model.checkCategoryExist();*/
+
+ model.insert();
+ }
+
+ public void updateGoods(UpdateGoodsCommand command) {
+ GoodsModel model = goodsModelFactory.loadById(command.getGoodsId());
+ model.loadUpdateGoodsCommand(command);
+
+/* model.checkGoodsNameUnique();
+ model.checkCategoryExist();*/
+
+ model.updateById();
+ }
+
+ public void deleteGoods(BulkOperationCommand command) {
+ for (Long goodsId : command.getIds()) {
+ GoodsModel model = goodsModelFactory.loadById(goodsId);
+ model.deleteById();
+ }
+ }
}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/command/AddGoodsCommand.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/command/AddGoodsCommand.java
new file mode 100644
index 0000000..5778dab
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/command/AddGoodsCommand.java
@@ -0,0 +1,11 @@
+package com.agileboot.domain.shop.goods.command;
+
+import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class AddGoodsCommand extends ShopGoodsEntity {
+
+}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/command/UpdateGoodsCommand.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/command/UpdateGoodsCommand.java
new file mode 100644
index 0000000..dde4a71
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/command/UpdateGoodsCommand.java
@@ -0,0 +1,10 @@
+package com.agileboot.domain.shop.goods.command;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class UpdateGoodsCommand extends AddGoodsCommand {
+
+}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/SearchGoodsDO.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/SearchGoodsDO.java
index 9539b03..3af909e 100644
--- a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/SearchGoodsDO.java
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/SearchGoodsDO.java
@@ -7,4 +7,5 @@ import lombok.EqualsAndHashCode;
@Data
public class SearchGoodsDO extends ShopGoodsEntity {
+ private String categoryName;
}
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/ShopGoodsMapper.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/ShopGoodsMapper.java
index 04401dc..7dba089 100644
--- a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/ShopGoodsMapper.java
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/ShopGoodsMapper.java
@@ -23,9 +23,9 @@ public interface ShopGoodsMapper extends BaseMapper {
* @return 商品分页列表
*/
@Select("SELECT g.goods_id, g.goods_name, g.category_id, g.price, " +
- "g.stock, g.status, g.cover_img " +
+ "g.stock, g.status, g.cover_img, c.category_name " +
"FROM shop_goods g " +
-// "LEFT JOIN shop_category c ON g.category_id = c.category_id " +
+ "LEFT JOIN shop_category c ON g.category_id = c.category_id " +
"${ew.customSqlSegment}")
Page getGoodsList(
Page page,
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/impl/ShopGoodsServiceImpl.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/ShopGoodsServiceImpl.java
similarity index 69%
rename from agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/impl/ShopGoodsServiceImpl.java
rename to agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/ShopGoodsServiceImpl.java
index 8e4587b..346d294 100644
--- a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/impl/ShopGoodsServiceImpl.java
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/db/ShopGoodsServiceImpl.java
@@ -1,13 +1,9 @@
-package com.agileboot.domain.shop.goods.db.impl;
+package com.agileboot.domain.shop.goods.db;
import com.agileboot.common.core.page.AbstractPageQuery;
-import com.agileboot.domain.shop.goods.db.SearchGoodsDO;
-import com.agileboot.domain.shop.goods.db.ShopGoodsService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
-import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
-import com.agileboot.domain.shop.goods.db.ShopGoodsMapper;
/**
*
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/model/GoodsModel.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/model/GoodsModel.java
new file mode 100644
index 0000000..30172b4
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/model/GoodsModel.java
@@ -0,0 +1,71 @@
+package com.agileboot.domain.shop.goods.model;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.agileboot.common.config.AgileBootConfig;
+import com.agileboot.common.exception.ApiException;
+import com.agileboot.common.exception.error.ErrorCode;
+import com.agileboot.domain.shop.category.db.ShopCategoryService;
+import com.agileboot.domain.shop.goods.command.AddGoodsCommand;
+import com.agileboot.domain.shop.goods.command.UpdateGoodsCommand;
+import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
+import com.agileboot.domain.shop.goods.db.ShopGoodsService;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class GoodsModel extends ShopGoodsEntity {
+
+ private ShopGoodsService goodsService;
+ private ShopCategoryService categoryService;
+
+ public GoodsModel(ShopGoodsEntity entity, ShopGoodsService goodsService,
+ ShopCategoryService categoryService) {
+ this(goodsService, categoryService);
+ if (entity != null) {
+ BeanUtil.copyProperties(entity, this);
+ }
+ }
+
+ public GoodsModel(ShopGoodsService goodsService, ShopCategoryService categoryService) {
+ this.goodsService = goodsService;
+ this.categoryService = categoryService;
+ }
+
+ public void loadAddGoodsCommand(AddGoodsCommand command) {
+ if (command != null) {
+ BeanUtil.copyProperties(command, this, "goodsId");
+ }
+ }
+
+ public void loadUpdateGoodsCommand(UpdateGoodsCommand command) {
+ if (command != null) {
+ loadAddGoodsCommand(command);
+ }
+ }
+
+/* public void checkGoodsNameUnique() {
+ if (goodsService.isGoodsNameDuplicated(getGoodsName(), getGoodsId())) {
+ throw new ApiException(ErrorCode.FAILED, "商品名称已存在");
+ }
+ }
+
+ public void checkCategoryExist() {
+ if (getCategoryId() != null && !categoryService.existsCategory(getCategoryId())) {
+ throw new ApiException(ErrorCode.FAILED, "商品分类不存在");
+ }
+ }*/
+
+ @Override
+ public boolean updateById() {
+ if (AgileBootConfig.isDemoEnabled() && isSpecialGoods()) {
+ throw new ApiException(ErrorCode.FAILED);
+ }
+ return super.updateById();
+ }
+
+ // 示例方法:判断是否为特殊商品(可根据业务需求实现)
+ private boolean isSpecialGoods() {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/model/GoodsModelFactory.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/model/GoodsModelFactory.java
new file mode 100644
index 0000000..76eae67
--- /dev/null
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/model/GoodsModelFactory.java
@@ -0,0 +1,29 @@
+package com.agileboot.domain.shop.goods.model;
+
+import com.agileboot.common.exception.ApiException;
+import com.agileboot.common.exception.error.ErrorCode;
+import com.agileboot.domain.shop.category.db.ShopCategoryService;
+import com.agileboot.domain.shop.goods.db.ShopGoodsEntity;
+import com.agileboot.domain.shop.goods.db.ShopGoodsService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class GoodsModelFactory {
+
+ private final ShopGoodsService goodsService;
+ private final ShopCategoryService categoryService;
+
+ public GoodsModel loadById(Long goodsId) {
+ ShopGoodsEntity entity = goodsService.getById(goodsId);
+ if (entity == null) {
+ throw new ApiException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, goodsId, "商品");
+ }
+ return new GoodsModel(entity, goodsService, categoryService);
+ }
+
+ public GoodsModel create() {
+ return new GoodsModel(goodsService, categoryService);
+ }
+}
\ No newline at end of file
diff --git a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/query/SearchShopGoodsQuery.java b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/query/SearchShopGoodsQuery.java
index 50469bd..760ffec 100644
--- a/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/query/SearchShopGoodsQuery.java
+++ b/agileboot-domain/src/main/java/com/agileboot/domain/shop/goods/query/SearchShopGoodsQuery.java
@@ -22,12 +22,12 @@ public class SearchShopGoodsQuery extends AbstractPageQuery {
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper
- .like(StrUtil.isNotEmpty(goodsName), "goods_name", goodsName)
- .eq(categoryId != null, "category_id", categoryId)
- .eq(status != null, "status", status)
- .ge(minPrice != null, "price", minPrice)
- .le(maxPrice != null, "price", maxPrice)
- .eq("deleted", 0);
+ .like(StrUtil.isNotEmpty(goodsName), "g.goods_name", goodsName)
+ .eq(categoryId != null, "g.category_id", categoryId)
+ .eq(status != null, "g.status", status)
+ .ge(minPrice != null, "g.price", minPrice)
+ .le(maxPrice != null, "g.price", maxPrice)
+ .eq("g.deleted", 0);
this.timeRangeColumn = "create_time";
diff --git a/agileboot-domain/src/main/resources/mapper/shop/ShopCategoryMapper.xml b/agileboot-domain/src/main/resources/mapper/shop/ShopCategoryMapper.xml
new file mode 100644
index 0000000..a686d8a
--- /dev/null
+++ b/agileboot-domain/src/main/resources/mapper/shop/ShopCategoryMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/agileboot-infrastructure/src/main/java/com/agileboot/infrastructure/mybatisplus/CodeGenerator.java b/agileboot-infrastructure/src/main/java/com/agileboot/infrastructure/mybatisplus/CodeGenerator.java
index ec1496a..db98377 100644
--- a/agileboot-infrastructure/src/main/java/com/agileboot/infrastructure/mybatisplus/CodeGenerator.java
+++ b/agileboot-infrastructure/src/main/java/com/agileboot/infrastructure/mybatisplus/CodeGenerator.java
@@ -61,7 +61,7 @@ public class CodeGenerator {
//生成的类 放在orm子模块下的/target/generated-code目录底下
.module("/agileboot-orm/target/generated-code")
.parentPackage("com.agileboot")
- .tableName("shop_goods")
+ .tableName("shop_category")
// 决定是否继承基类
.isExtendsFromBaseEntity(true)
.build();
diff --git a/sql/20250304.sql b/sql/20250304.sql
new file mode 100644
index 0000000..f42a45c
--- /dev/null
+++ b/sql/20250304.sql
@@ -0,0 +1,35 @@
+CREATE TABLE `shop_goods` (
+ `goods_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '商品唯一ID',
+ `goods_name` VARCHAR(255) NOT NULL COMMENT '商品名称',
+ `category_id` BIGINT NOT NULL COMMENT '商品分类ID',
+ `price` DECIMAL(15,2) NOT NULL DEFAULT 0.00 COMMENT '销售价格',
+ `stock` INT NOT NULL DEFAULT 0 COMMENT '库存数量',
+ `status` TINYINT NOT NULL DEFAULT 2 COMMENT '商品状态(1上架 2下架)',
+ `cover_img` VARCHAR(512) COMMENT '封面图URL',
+ `goods_detail` TEXT NOT NULL COMMENT '商品详情(支持2000汉字+10个图片链接)',
+ `creator_id` BIGINT NOT NULL DEFAULT 0 COMMENT '创建者ID',
+ `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater_id` BIGINT NOT NULL DEFAULT 0 COMMENT '更新者ID',
+ `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `remark` VARCHAR(512) DEFAULT NULL COMMENT '备注',
+ `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '删除标志(0存在 1删除)',
+ PRIMARY KEY (`goods_id`),
+ KEY `idx_category` (`category_id`),
+ KEY `idx_status` (`status`),
+ KEY `idx_update_time` (`update_time`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商品信息表';
+
+CREATE TABLE `shop_category` (
+ `category_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '分类唯一ID',
+ `category_name` VARCHAR(255) NOT NULL COMMENT '分类名称',
+ `sort` INT NOT NULL DEFAULT 0 COMMENT '排序权重',
+ `description` VARCHAR(512) DEFAULT NULL COMMENT '分类描述',
+ `creator_id` BIGINT NOT NULL DEFAULT 0 COMMENT '创建者ID',
+ `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater_id` BIGINT NOT NULL DEFAULT 0 COMMENT '更新者ID',
+ `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '删除标志(0存在 1删除)',
+ PRIMARY KEY (`category_id`),
+ KEY `idx_sort` (`sort`),
+ KEY `idx_update_time` (`update_time`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商品分类表';
\ No newline at end of file