From 6d31d535d737ed26c4d9d61cd4e0b5483cb9b0ba Mon Sep 17 00:00:00 2001
From: xin <1099200748@qq.com>
Date: Wed, 17 Sep 2025 19:44:00 +0800
Subject: [PATCH] Merge branch 'refs/heads/master' into xin
---
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java | 19 ---
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductInventoryUpdateRequest.java | 13 ++
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java | 3
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java | 7 +
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java | 3
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductInventoryServiceImpl.java | 59 +++++++++++
oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java | 4
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java | 3
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java | 16 ++
oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductStockMapper.java | 23 ++++
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductInventoryService.java | 11 ++
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductInventoryController.java | 54 ++++++++++
oying-system/src/main/resources/mapper/pc/product/ProductStockMapper.xml | 49 +++++++++
13 files changed, 239 insertions(+), 25 deletions(-)
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductInventoryUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductInventoryUpdateRequest.java
new file mode 100644
index 0000000..2bc2000
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductInventoryUpdateRequest.java
@@ -0,0 +1,13 @@
+package com.oying.modules.pc.product.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class ProductInventoryUpdateRequest {
+
+ private Long productId;
+ private Integer quantity;
+ private Integer amount;
+ private Long version;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductStockMapper.java b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductStockMapper.java
new file mode 100644
index 0000000..227cea8
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductStockMapper.java
@@ -0,0 +1,23 @@
+package com.oying.modules.pc.product.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.oying.modules.pc.product.domain.Product;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface ProductStockMapper extends BaseMapper<Product> {
+
+ List<Product> selectLowStockProducts(@Param("threshold") Integer threshold);
+
+ int updateStock(@Param("productId") Long productId, @Param("quantity") Integer quantity, @Param("version") Long version);
+
+ int increaseStock(@Param("productId") Long productId, @Param("amount") Integer amount, @Param("version") Long version);
+
+ int decreaseStock(@Param("productId") Long productId, @Param("amount") Integer amount, @Param("version") Long version);
+
+ int batchUpdateStock(List<Product> products);
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductInventoryController.java b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductInventoryController.java
new file mode 100644
index 0000000..7d5d4ca
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductInventoryController.java
@@ -0,0 +1,54 @@
+package com.oying.modules.pc.product.rest;
+
+import com.oying.modules.pc.product.domain.Product;
+import com.oying.modules.pc.product.domain.dto.ProductInventoryUpdateRequest;
+import com.oying.modules.pc.product.service.ProductInventoryService;
+import com.oying.utils.R;
+import io.swagger.annotations.Api;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Optional;
+
+/**
+ * @author lzp
+ * @date 2025-09-10
+ **/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "商品库存")
+@RequestMapping("/api/pc/product/{productId}/inventory")
+public class ProductInventoryController {
+
+ private final ProductInventoryService productInventoryService;
+
+ @GetMapping
+ public ResponseEntity<?> getStockInfo(@PathVariable Long productId) {
+ return ResponseEntity.ok(R.success(productInventoryService.getProductById(productId)));
+ }
+
+ @PutMapping
+ public ResponseEntity<?> setStock(@PathVariable Long productId, @RequestBody ProductInventoryUpdateRequest request) {
+ Product product = productInventoryService.setStockQuantity(Optional.ofNullable(request.getProductId()).orElse(productId), request.getQuantity(), request.getVersion());
+ return ResponseEntity.ok(R.success(product));
+ }
+
+ @PostMapping("/increase")
+ public ResponseEntity<?> increaseStock(@PathVariable Long productId, @RequestBody ProductInventoryUpdateRequest request) {
+ Product product = productInventoryService.increaseStock(Optional.ofNullable(request.getProductId()).orElse(productId), request.getAmount());
+ return ResponseEntity.ok(R.success(product));
+ }
+
+ @PostMapping("/decrease")
+ public ResponseEntity<?> decreaseStock(@PathVariable Long productId, @RequestBody ProductInventoryUpdateRequest request) {
+ Product product = productInventoryService.decreaseStock(Optional.ofNullable(request.getProductId()).orElse(productId), request.getAmount());
+ return ResponseEntity.ok(R.success(product));
+ }
+
+ @GetMapping("/sufficient")
+ public ResponseEntity<?> checkStockSufficient(@PathVariable Long productId, @RequestParam Integer requiredAmount) {
+ boolean isSufficient = productInventoryService.isStockSufficient(productId, requiredAmount);
+ return ResponseEntity.ok(R.success(isSufficient));
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductInventoryService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductInventoryService.java
new file mode 100644
index 0000000..c425722
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductInventoryService.java
@@ -0,0 +1,11 @@
+package com.oying.modules.pc.product.service;
+
+import com.oying.modules.pc.product.domain.Product;
+
+public interface ProductInventoryService {
+ Product getProductById(Long id);
+ Product setStockQuantity(Long product, Integer quantity, Long version);
+ Product increaseStock(Long product, Integer amount);
+ Product decreaseStock(Long product, Integer amount);
+ boolean isStockSufficient(Long productId, Integer requiredAmount);
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java
index a610f1d..026338f 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java
@@ -33,6 +33,13 @@
List<Product> queryAll(ProductQueryCriteria criteria);
/**
+ * 根据ID查询数据
+ * @param productId ID
+ * @return product
+ */
+ Product getProduct(Long productId);
+
+ /**
* 创建
* @param resources /
*/
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductInventoryServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductInventoryServiceImpl.java
new file mode 100644
index 0000000..896cb23
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductInventoryServiceImpl.java
@@ -0,0 +1,59 @@
+package com.oying.modules.pc.product.service.impl;
+
+import com.oying.modules.pc.product.domain.Product;
+import com.oying.modules.pc.product.mapper.ProductStockMapper;
+import com.oying.modules.pc.product.service.ProductInventoryService;
+import com.oying.modules.pc.product.service.ProductService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@RequiredArgsConstructor
+public class ProductInventoryServiceImpl implements ProductInventoryService {
+
+ private final ProductStockMapper productStockMapper;
+ private final ProductService productService;
+
+ @Override
+ public Product getProductById(Long productId) {
+ return productService.getProduct(productId);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Product setStockQuantity(Long productId, Integer quantity, Long version) {
+ Product existingProduct = this.getProductById(productId);
+ productStockMapper.updateStock(productId, quantity, existingProduct.getVersion());
+ return this.getProductById(productId);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Product increaseStock(Long productId, Integer amount) {
+ Product existingProduct = this.getProductById(productId);
+ productStockMapper.increaseStock(productId, amount, existingProduct.getVersion());
+ return getProductById(productId);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Product decreaseStock(Long productId, Integer amount) {
+ Product existingProduct = this.getProductById(productId);
+ if (existingProduct.getStockQuantity() < amount) {
+ throw new RuntimeException("库存不足,当前库存: " + existingProduct.getStockQuantity() + ", 请求数量: " + amount);
+ }
+ productStockMapper.decreaseStock(productId, amount, existingProduct.getVersion());
+ return getProductById(productId);
+ }
+
+ @Override
+ public boolean isStockSufficient(Long productId, Integer requiredAmount) {
+ if (requiredAmount == null || requiredAmount <= 0) {
+ throw new IllegalArgumentException("需求数量必须大于0");
+ }
+ Product existingProduct = this.getProductById(productId);
+ return existingProduct.getStockQuantity() >= requiredAmount;
+ }
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java
index 24ed038..e4eef20 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java
@@ -1,11 +1,9 @@
package com.oying.modules.pc.product.service.impl;
import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.oying.exception.BadRequestException;
-import com.oying.exception.EntityNotFoundException;
import com.oying.modules.pc.common.core.constrant.AuditStatusEnum;
import com.oying.modules.pc.product.converter.ProductImageAssembler;
import com.oying.modules.pc.product.converter.ProductLabelAssembler;
@@ -30,7 +28,6 @@
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
-import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -77,7 +74,7 @@
@Override
@Transactional(rollbackFor = Exception.class)
public void update(ProductMerchantUpdateRequest request) {
- Product existingProduct = this.findOrThrow(request.getProductId());
+ Product existingProduct = productService.getProduct(request.getProductId());
this.validateApprovedStatus(existingProduct.getShelfStatus());
this.processImagesUpdate(request);
this.processLabelsUpdate(request);
@@ -88,18 +85,16 @@
@Override
@Transactional(rollbackFor = Exception.class)
public void updateImages(ProductMerchantUpdateRequest request) {
- Product existingProduct = this.findOrThrow(request.getProductId());
+ Product existingProduct = productService.getProduct(request.getProductId());
this.validateApprovedStatus(existingProduct.getShelfStatus());
- this.findOrThrow(request.getProductId());
this.processImagesUpdate(request);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateLabels(ProductMerchantUpdateRequest request) {
- Product existingProduct = this.findOrThrow(request.getProductId());
+ Product existingProduct = productService.getProduct(request.getProductId());
this.validateApprovedStatus(existingProduct.getShelfStatus());
- this.findOrThrow(request.getProductId());
this.processImagesUpdate(request);
}
@@ -160,14 +155,6 @@
} catch (Exception e) {
log.error("处理商品审核结果异常", e);
}
- }
-
- private Product findOrThrow(Long productId) {
- Product existingProduct = productService.getById(productId);
- if (ObjUtil.isEmpty(existingProduct)) {
- throw new EntityNotFoundException(Product.class, "id", Optional.ofNullable(productId).map(Object::toString).orElse("null"));
- }
- return existingProduct;
}
private void processImagesUpdate(ProductMerchantUpdateRequest request) {
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java
index 879e105..5e609ea 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java
@@ -1,8 +1,10 @@
package com.oying.modules.pc.product.service.impl;
+import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.oying.exception.EntityNotFoundException;
import com.oying.modules.pc.product.domain.Product;
import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
import com.oying.modules.pc.product.mapper.ProductMapper;
@@ -16,10 +18,7 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* @author lzp
@@ -43,6 +42,15 @@
}
@Override
+ public Product getProduct(Long productId) {
+ Product existingProduct = getById(productId);
+ if (ObjUtil.isEmpty(existingProduct)) {
+ throw new EntityNotFoundException(Product.class, "id", Optional.ofNullable(productId).map(Object::toString).orElse("null"));
+ }
+ return existingProduct;
+ }
+
+ @Override
@Transactional(rollbackFor = Exception.class)
public void create(Product resources) {
productMapper.insert(resources);
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java
index 4d21d17..b2e5dea 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java
@@ -14,10 +14,12 @@
Store store = new Store();
BeanUtil.copyProperties(request, store, CopyOptions.create().setIgnoreNullValue(true));
- store.setMerchantId(SecurityUtils.getCurrentUserId());
+ // 由前端传入,不允许修改
+ //store.setMerchantId(SecurityUtils.getCurrentUserId());
Long logoUploadFileId = request.getLogoUploadFileId();
store.setLogoImageId(logoUploadFileId);
store.setLogoImageUrl(ImageUtils.getPublicObjectUrl(logoUploadFileId));
+
Long coverUploadFileId = request.getCoverUploadFileId();
store.setCoverImageId(coverUploadFileId);
store.setCoverImageUrl(ImageUtils.getPublicObjectUrl(coverUploadFileId));
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java
index 05c2404..a99b340 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java
@@ -23,6 +23,9 @@
@ApiModelProperty(value = "店铺简称", example = "永辉超市(新纪元店)")
private String storeShortName;*/
+ @ApiModelProperty(value = "商户ID")
+ private Long merchantId;
+
@NotNull
@ApiModelProperty(value = "店铺LOGO文件ID", example = "14567785444763247876234")
private Long logoUploadFileId;
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java
index bf35cd7..de71ed4 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java
@@ -26,9 +26,6 @@
@ApiModelProperty(value = "店铺ID")
private Long storeId;
- @ApiModelProperty(value = "商户ID")
- private Long merchantId;
-
@ApiModelProperty(value = "平台类目")
private Long platformCategoryId;
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
index 4b09b6a..b89bb58 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
@@ -21,6 +21,7 @@
import com.oying.utils.PageUtil;
import com.oying.utils.SecurityUtils;
import com.oying.utils.StringUtils;
+import com.oying.utils.enums.StoreRole;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -262,7 +263,7 @@
StoreUser storeUser = new StoreUser();
storeUser.setStoreId(storeId);
storeUser.setUserId(SecurityUtils.getCurrentUserId());
- storeUser.setRoleType("");
+ storeUser.setRoleType(StoreRole.ADMIN.getRole());
storeUser.setPermissions("");
storeUserMapper.insert(storeUser);
return true;
diff --git a/oying-system/src/main/resources/mapper/pc/product/ProductStockMapper.xml b/oying-system/src/main/resources/mapper/pc/product/ProductStockMapper.xml
new file mode 100644
index 0000000..c712189
--- /dev/null
+++ b/oying-system/src/main/resources/mapper/pc/product/ProductStockMapper.xml
@@ -0,0 +1,49 @@
+<?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.oying.modules.pc.product.mapper.ProductStockMapper">
+
+ <!-- 更新库存 -->
+ <update id="updateStock">
+ UPDATE pc_product SET
+ stock_quantity = #{quantity},
+ version = version + 1
+ WHERE
+ product_id = #{productId} AND version = #{version}
+ </update>
+
+ <!-- 批量更新库存 -->
+ <update id="batchUpdateStock" parameterType="list">
+ <foreach collection="list" item="item" index="index" separator=";">
+ UPDATE products
+ SET stock_quantity = #{item.quantity}, version = version + 1
+ WHERE
+ product_id = #{item.productId} AND version = #{item.version}
+ </foreach>
+ </update>
+
+ <!-- 增加库存 -->
+ <update id="increaseStock">
+ UPDATE pc_product SET
+ stock_quantity = stock_quantity + #{amount},
+ version = version + 1
+ WHERE
+ product_id = #{productId} AND version = #{version}
+ </update>
+
+ <!-- 减少库存 -->
+ <update id="decreaseStock">
+ UPDATE pc_product SET
+ stock_quantity = stock_quantity - #{amount},
+ version = version + 1
+ WHERE
+ product_id = #{productId} AND version = #{version}
+ </update>
+
+ <!-- 查询最低库存商品 -->
+ <select id="selectLowStockProducts">
+ SELECT * FROM products
+ WHERE stock_quantity <![CDATA[ <= ]]> #{threshold}
+ ORDER BY stock_quantity ASC
+ </select>
+
+</mapper>
\ No newline at end of file
--
Gitblit v1.9.3