Commit d92d2576196ffca0e881385194d496efda26c91f

Authored by luowenfeng
2 parents dc4e3fcd 7bf37fcb

Merge branch 'feature/1.8.0-uniapp' of https://gitee.com/zhijiantianya/ruoyi-vue…

…-pro into feature/1.8.0-uniapp

 Conflicts:
	yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
	yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
Showing 16 changed files with 133 additions and 193 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/SpuInfoRespDTO.java
@@ -31,7 +31,7 @@ public class SpuInfoRespDTO { @@ -31,7 +31,7 @@ public class SpuInfoRespDTO {
31 */ 31 */
32 private String code; 32 private String code;
33 /** 33 /**
34 - * 商品卖点 34 + * 促销语
35 */ 35 */
36 private String sellPoint; 36 private String sellPoint;
37 /** 37 /**
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo; 1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
2 2
3 import cn.iocoder.yudao.framework.common.validation.InEnum; 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;  
5 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; 4 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
6 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; 5 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
7 import io.swagger.annotations.ApiModelProperty; 6 import io.swagger.annotations.ApiModelProperty;
@@ -25,7 +24,7 @@ public class ProductSpuBaseVO { @@ -25,7 +24,7 @@ public class ProductSpuBaseVO {
25 @ApiModelProperty(value = "商品编码", example = "yudaoyuanma") 24 @ApiModelProperty(value = "商品编码", example = "yudaoyuanma")
26 private String code; 25 private String code;
27 26
28 - @ApiModelProperty(value = "商品卖点", example = "好吃!") 27 + @ApiModelProperty(value = "促销语", example = "好吃!")
29 private String sellPoint; 28 private String sellPoint;
30 29
31 @ApiModelProperty(value = "商品详情", required = true, example = "我是商品描述") 30 @ApiModelProperty(value = "商品详情", required = true, example = "我是商品描述")
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java
1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo; 1 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
2 2
3 -import lombok.*;  
4 -import java.util.*;  
5 -import io.swagger.annotations.*;  
6 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
7 -import org.springframework.format.annotation.DateTimeFormat;  
8 -  
9 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 4 +import io.swagger.annotations.ApiModel;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
10 9
11 @ApiModel("管理后台 - 商品 SPU 分页 Request VO") 10 @ApiModel("管理后台 - 商品 SPU 分页 Request VO")
12 @Data 11 @Data
@@ -26,7 +25,7 @@ public class ProductSpuPageReqVO extends PageParam { @@ -26,7 +25,7 @@ public class ProductSpuPageReqVO extends PageParam {
26 @ApiModelProperty(value = "商品品牌编号", example = "1") 25 @ApiModelProperty(value = "商品品牌编号", example = "1")
27 private Long brandId; 26 private Long brandId;
28 27
29 - @ApiModelProperty(value = "上下架状态", example = "1", notes = "参见 CommonStatusEnum 枚举值") 28 + @ApiModelProperty(value = "上下架状态", example = "1", notes = "参见 ProductSpuStatusEnum 枚举值")
30 private Integer status; 29 private Integer status;
31 30
32 @ApiModelProperty(value = "销量最小值", example = "1") 31 @ApiModelProperty(value = "销量最小值", example = "1")
@@ -41,8 +40,7 @@ public class ProductSpuPageReqVO extends PageParam { @@ -41,8 +40,7 @@ public class ProductSpuPageReqVO extends PageParam {
41 @ApiModelProperty(value = "市场价最大值", example = "1024") 40 @ApiModelProperty(value = "市场价最大值", example = "1024")
42 private Integer marketPriceMax; 41 private Integer marketPriceMax;
43 42
44 - // TODO @luowenfeng: 这个可以改成前端基于 tab, 传递不同的条件么?  
45 - @ApiModelProperty(value = "tab 状态 null 全部, 0:销售中(上架) 1:仓库中(下架) 2:预警中", example = "1")  
46 - private Integer tabStatus; 43 + @ApiModelProperty(value = "是否库存告警", example = "true")
  44 + private Boolean alarmStock;
47 45
48 } 46 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
@@ -47,7 +47,7 @@ public class ProductSpuDO extends BaseDO { @@ -47,7 +47,7 @@ public class ProductSpuDO extends BaseDO {
47 */ 47 */
48 private String code; 48 private String code;
49 /** 49 /**
50 - * 商品卖点 50 + * 促销语
51 */ 51 */
52 private String sellPoint; 52 private String sellPoint;
53 /** 53 /**
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
@@ -40,7 +40,7 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> { @@ -40,7 +40,7 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
40 } 40 }
41 } 41 }
42 42
43 - default List<ProductSkuDO> selectListByRemind(){ 43 + default List<ProductSkuDO> selectListByAlarmStock(){
44 return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock")); 44 return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
45 } 45 }
46 46
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
@@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReq @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReq
7 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 7 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
8 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
9 9
10 -import java.util.List; 10 +import java.util.Set;
11 11
12 /** 12 /**
13 * 商品spu Mapper 13 * 商品spu Mapper
@@ -29,8 +29,8 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; { @@ -29,8 +29,8 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; {
29 .orderByDesc(ProductSpuDO::getSort)); 29 .orderByDesc(ProductSpuDO::getSort));
30 } 30 }
31 31
32 - default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO, List<Long> spuIds) {  
33 - LambdaQueryWrapperX<ProductSpuDO> productSpuDOLambdaQueryWrapperX = new LambdaQueryWrapperX<ProductSpuDO>() 32 + default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO, Set<Long> alarmStockSpuIds) {
  33 + return selectPage(reqVO, new LambdaQueryWrapperX<ProductSpuDO>()
34 .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) 34 .likeIfPresent(ProductSpuDO::getName, reqVO.getName())
35 .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) 35 .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId())
36 .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) 36 .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus())
@@ -38,16 +38,9 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; { @@ -38,16 +38,9 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; {
38 .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) 38 .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin())
39 .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) 39 .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax())
40 .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) 40 .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin())
41 - .orderByDesc(ProductSpuDO::getSort);  
42 - // TODO @芋艿: 需要优化下这里的代码  
43 - if(reqVO.getTabStatus()!= null && reqVO.getTabStatus() == 2){  
44 - productSpuDOLambdaQueryWrapperX.inIfPresent(ProductSpuDO::getId, spuIds);  
45 - }else{  
46 - productSpuDOLambdaQueryWrapperX.eqIfPresent(ProductSpuDO::getStatus, reqVO.getTabStatus());  
47 - }  
48 -  
49 - return selectPage(reqVO, productSpuDOLambdaQueryWrapperX); 41 + .inIfPresent(ProductSpuDO::getId, alarmStockSpuIds) // 库存告警
  42 + .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus())
  43 + .orderByDesc(ProductSpuDO::getSort));
50 } 44 }
51 45
52 -  
53 } 46 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.product.service.sku; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.product.service.sku;
3 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; 3 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
4 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; 4 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
5 5
6 -import javax.validation.Valid;  
7 import java.util.Collection; 6 import java.util.Collection;
8 import java.util.List; 7 import java.util.List;
9 8
@@ -84,10 +83,10 @@ public interface ProductSkuService { @@ -84,10 +83,10 @@ public interface ProductSkuService {
84 void deleteSkuBySpuId(Long spuId); 83 void deleteSkuBySpuId(Long spuId);
85 84
86 /** 85 /**
87 - * 获得商品预警中的 SPU 集合 86 + * 获得库存预警的 SKU 数组
88 * 87 *
89 - * @return 商品spuId集合 88 + * @return SKU 数组
90 */ 89 */
91 - List<ProductSkuDO> getRemindSpuIds(); 90 + List<ProductSkuDO> getSkusByAlarmStock();
92 91
93 } 92 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
1 package cn.iocoder.yudao.module.product.service.sku; 1 package cn.iocoder.yudao.module.product.service.sku;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.collection.CollectionUtil;  
5 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
6 -import cn.hutool.core.util.StrUtil;  
7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
9 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; 5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
10 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; 6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
11 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; 7 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
@@ -17,18 +13,15 @@ import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; @@ -17,18 +13,15 @@ import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants;
17 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; 13 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
18 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; 14 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
19 import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; 15 import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
20 -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;  
21 import org.springframework.stereotype.Service; 16 import org.springframework.stereotype.Service;
22 import org.springframework.transaction.annotation.Transactional; 17 import org.springframework.transaction.annotation.Transactional;
23 import org.springframework.validation.annotation.Validated; 18 import org.springframework.validation.annotation.Validated;
24 19
25 import javax.annotation.Resource; 20 import javax.annotation.Resource;
26 import java.util.*; 21 import java.util.*;
27 -import java.util.function.Function;  
28 import java.util.stream.Collectors; 22 import java.util.stream.Collectors;
29 23
30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
31 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;  
32 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; 25 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
33 26
34 /** 27 /**
@@ -138,8 +131,8 @@ public class ProductSkuServiceImpl implements ProductSkuService { @@ -138,8 +131,8 @@ public class ProductSkuServiceImpl implements ProductSkuService {
138 } 131 }
139 132
140 @Override 133 @Override
141 - public List<ProductSkuDO> getRemindSpuIds() {  
142 - return productSkuMapper.selectListByRemind(); 134 + public List<ProductSkuDO> getSkusByAlarmStock() {
  135 + return productSkuMapper.selectListByAlarmStock();
143 } 136 }
144 137
145 @Override 138 @Override
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
1 package cn.iocoder.yudao.module.product.service.spu; 1 package cn.iocoder.yudao.module.product.service.spu;
2 2
3 import cn.hutool.core.bean.BeanUtil; 3 import cn.hutool.core.bean.BeanUtil;
  4 +import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO; 7 import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
@@ -28,10 +29,7 @@ import org.springframework.transaction.annotation.Transactional; @@ -28,10 +29,7 @@ import org.springframework.transaction.annotation.Transactional;
28 import org.springframework.validation.annotation.Validated; 29 import org.springframework.validation.annotation.Validated;
29 30
30 import javax.annotation.Resource; 31 import javax.annotation.Resource;
31 -import java.util.ArrayList;  
32 -import java.util.Collection;  
33 -import java.util.List;  
34 -import java.util.Map; 32 +import java.util.*;
35 import java.util.stream.Collectors; 33 import java.util.stream.Collectors;
36 34
37 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 35 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -180,18 +178,21 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -180,18 +178,21 @@ public class ProductSpuServiceImpl implements ProductSpuService {
180 178
181 @Override 179 @Override
182 public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) { 180 public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) {
183 - List<Long> remindSpuIds = null;  
184 - if (pageReqVO.getTabStatus() != null && pageReqVO.getTabStatus() == 2) {  
185 - remindSpuIds = productSkuService.getRemindSpuIds().stream().map(ProductSkuDO::getSpuId).distinct().collect(Collectors.toList());  
186 - if (remindSpuIds.isEmpty()) {  
187 - remindSpuIds.add(null); 181 + // 库存告警的 SPU 编号的集合
  182 + Set<Long> alarmStockSpuIds = null;
  183 + if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) {
  184 + alarmStockSpuIds = CollectionUtils.convertSet(productSkuService.getSkusByAlarmStock(), ProductSkuDO::getSpuId);
  185 + if (CollUtil.isEmpty(alarmStockSpuIds)) {
  186 + return PageResult.empty();
188 } 187 }
189 } 188 }
190 - return ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(pageReqVO, remindSpuIds)); 189 + // 分页查询
  190 + return ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds));
191 } 191 }
192 192
193 @Override 193 @Override
194 public PageResult<AppSpuPageRespVO> getSpuPage(AppSpuPageReqVO pageReqVO) { 194 public PageResult<AppSpuPageRespVO> getSpuPage(AppSpuPageReqVO pageReqVO) {
  195 + // TODO 芋艿:貌似实现不太合理
195 PageResult<ProductSpuDO> productSpuDOPageResult = productSpuMapper.selectPage(ProductSpuConvert.INSTANCE.convert(pageReqVO)); 196 PageResult<ProductSpuDO> productSpuDOPageResult = productSpuMapper.selectPage(ProductSpuConvert.INSTANCE.convert(pageReqVO));
196 PageResult<AppSpuPageRespVO> pageResult = new PageResult<>(); 197 PageResult<AppSpuPageRespVO> pageResult = new PageResult<>();
197 // TODO @芋艿 这里用convert如何解决 198 // TODO @芋艿 这里用convert如何解决
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java
@@ -208,6 +208,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { @@ -208,6 +208,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
208 Assertions.assertIterableEquals(createReqVO, spuList); 208 Assertions.assertIterableEquals(createReqVO, spuList);
209 } 209 }
210 210
  211 + // TODO @luowenfeng:单测要分情况;类似你这个,可以分 2 个单测;一个是有预存预警的;一个是没库存预警的;
  212 + // 然后,参考其它模块的 getPage 类型的方法的单测。
211 @Test 213 @Test
212 void getSpuPage() { 214 void getSpuPage() {
213 // 准备参数 215 // 准备参数
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.service.order; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.service.order;
3 import cn.hutool.core.bean.BeanUtil; 3 import cn.hutool.core.bean.BeanUtil;
4 import cn.hutool.core.text.StrBuilder; 4 import cn.hutool.core.text.StrBuilder;
5 import cn.hutool.core.util.IdUtil; 5 import cn.hutool.core.util.IdUtil;
6 -import cn.hutool.core.util.StrUtil;  
7 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
8 import cn.iocoder.yudao.framework.common.enums.TerminalEnum; 7 import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
9 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; 8 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
@@ -15,8 +14,8 @@ import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; @@ -15,8 +14,8 @@ import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
15 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; 14 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
16 import cn.iocoder.yudao.module.pay.api.order.PayOrderInfoCreateReqDTO; 15 import cn.iocoder.yudao.module.pay.api.order.PayOrderInfoCreateReqDTO;
17 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; 16 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
18 -import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO;  
19 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 17 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  18 +import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO;
20 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; 19 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
21 import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO; 20 import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO;
22 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; 21 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
@@ -181,7 +180,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -181,7 +180,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
181 180
182 private void checkSaleableFromSpu(List<SpuInfoRespDTO> spuInfos) { 181 private void checkSaleableFromSpu(List<SpuInfoRespDTO> spuInfos) {
183 SpuInfoRespDTO spu = CollectionUtils.findFirst(spuInfos, 182 SpuInfoRespDTO spu = CollectionUtils.findFirst(spuInfos,
184 - spuInfoDTO -> !Objects.equals(ProductSpuStatusEnum.ENABLE.getStyle(), spuInfoDTO.getStatus())); 183 + spuInfoDTO -> !Objects.equals(ProductSpuStatusEnum.ENABLE.getStatus(), spuInfoDTO.getStatus()));
185 if (Objects.isNull(spu)) { 184 if (Objects.isNull(spu)) {
186 throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_SPU_NOT_SALE); 185 throw ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_SPU_NOT_SALE);
187 } 186 }
yudao-server/src/main/resources/application-local.yaml
@@ -45,33 +45,33 @@ spring: @@ -45,33 +45,33 @@ spring:
45 datasource: 45 datasource:
46 master: 46 master:
47 name: ruoyi-vue-pro 47 name: ruoyi-vue-pro
48 - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 48 + url: jdbc:mysql://139.9.196.247:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
49 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 49 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
50 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 50 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
51 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 51 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
52 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例 52 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例
53 username: root 53 username: root
54 - password: 123456 54 + password: ${RUOYI_VUE_PRO}
55 # username: sa 55 # username: sa
56 # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W 56 # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
57 slave: # 模拟从库,可根据自己需要修改 57 slave: # 模拟从库,可根据自己需要修改
58 name: ruoyi-vue-pro 58 name: ruoyi-vue-pro
59 - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 59 + url: jdbc:mysql://139.9.196.247:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
60 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 60 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
61 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 61 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
62 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 62 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
63 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例 63 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例
64 username: root 64 username: root
65 - password: 123456 65 + password: ${RUOYI_VUE_PRO}
66 # username: sa 66 # username: sa
67 # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W 67 # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
68 68
69 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 69 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
70 redis: 70 redis:
71 - host: 127.0.0.1 # 地址 71 + host: 139.9.196.247 # 地址
72 port: 6379 # 端口 72 port: 6379 # 端口
73 database: 0 # 数据库索引 73 database: 0 # 数据库索引
74 -# password: 123456 # 密码,建议生产环境开启 74 + password: 123456 # 密码,建议生产环境开启
75 75
76 jasypt: 76 jasypt:
77 encryptor: 77 encryptor:
yudao-ui-admin/src/utils/constants.js
@@ -185,37 +185,54 @@ export const PayOrderRefundStatusEnum = { @@ -185,37 +185,54 @@ export const PayOrderRefundStatusEnum = {
185 * 支付退款订单状态枚举 185 * 支付退款订单状态枚举
186 */ 186 */
187 export const PayRefundStatusEnum = { 187 export const PayRefundStatusEnum = {
188 - CREATE:{  
189 - status:0, 188 + CREATE: {
  189 + status: 0,
190 name: '退款订单生成' 190 name: '退款订单生成'
191 }, 191 },
192 - SUCCESS:{  
193 - status:1, 192 + SUCCESS: {
  193 + status: 1,
194 name: '退款成功' 194 name: '退款成功'
195 }, 195 },
196 - FAILURE:{  
197 - status:2, 196 + FAILURE: {
  197 + status: 2,
198 name: '退款失败' 198 name: '退款失败'
199 }, 199 },
200 - PROCESSING_NOTIFY:{  
201 - status:3, 200 + PROCESSING_NOTIFY: {
  201 + status: 3,
202 name: '退款中,渠道通知结果' 202 name: '退款中,渠道通知结果'
203 }, 203 },
204 - PROCESSING_QUERY:{  
205 - status:4, 204 + PROCESSING_QUERY: {
  205 + status: 4,
206 name: '退款中,系统查询结果' 206 name: '退款中,系统查询结果'
207 }, 207 },
208 - UNKNOWN_RETRY:{  
209 - status:5, 208 + UNKNOWN_RETRY: {
  209 + status: 5,
210 name: '状态未知,请重试' 210 name: '状态未知,请重试'
211 }, 211 },
212 - UNKNOWN_QUERY:{  
213 - status:6, 212 + UNKNOWN_QUERY: {
  213 + status: 6,
214 name: '状态未知,系统查询结果' 214 name: '状态未知,系统查询结果'
215 }, 215 },
216 - CLOSE:{  
217 - status:99, 216 + CLOSE: {
  217 + status: 99,
218 name: '退款关闭' 218 name: '退款关闭'
219 } 219 }
220 } 220 }
221 221
  222 +/**
  223 + * 商品 SPU 状态
  224 + */
  225 +export const ProductSpuStatusEnum = {
  226 + RECYCLE: {
  227 + status: -1,
  228 + name: '回收站'
  229 + },
  230 + DISABLE: {
  231 + status: 0,
  232 + name: '下架'
  233 + },
  234 + ENABLE: {
  235 + status: 1,
  236 + name: '上架'
  237 + },
  238 +}
yudao-ui-admin/src/utils/dict.js
@@ -56,6 +56,9 @@ export const DICT_TYPE = { @@ -56,6 +56,9 @@ export const DICT_TYPE = {
56 PAY_ORDER_REFUND_STATUS: 'pay_order_refund_status', // 商户支付订单退款状态 56 PAY_ORDER_REFUND_STATUS: 'pay_order_refund_status', // 商户支付订单退款状态
57 PAY_REFUND_ORDER_STATUS: 'pay_refund_order_status', // 退款订单状态 57 PAY_REFUND_ORDER_STATUS: 'pay_refund_order_status', // 退款订单状态
58 PAY_REFUND_ORDER_TYPE: 'pay_refund_order_type', // 退款订单类别 58 PAY_REFUND_ORDER_TYPE: 'pay_refund_order_type', // 退款订单类别
  59 +
  60 + // ========== MALL - PRODUCT 模块 ==========
  61 + PRODUCT_SPU_STATUS: 'product_spu_status', // 商品 SPU 状态
59 } 62 }
60 63
61 /** 64 /**
@@ -114,6 +117,3 @@ export function getDictDataLabel(dictType, value) { @@ -114,6 +117,3 @@ export function getDictDataLabel(dictType, value) {
114 const dict = getDictData(dictType, value); 117 const dict = getDictData(dictType, value);
115 return dict ? dict.label : ''; 118 return dict ? dict.label : '';
116 } 119 }
117 -  
118 -export class getDictDataL {  
119 -}  
yudao-ui-admin/src/views/mall/product/spu/index.vue
@@ -4,74 +4,48 @@ @@ -4,74 +4,48 @@
4 <el-form-item label="商品名称" prop="name"> 4 <el-form-item label="商品名称" prop="name">
5 <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/> 5 <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable @keyup.enter.native="handleQuery"/>
6 </el-form-item> 6 </el-form-item>
7 -  
8 <el-form-item label="商品编码" prop="code"> 7 <el-form-item label="商品编码" prop="code">
9 <el-input v-model="queryParams.code" placeholder="请输入商品编码" clearable @keyup.enter.native="handleQuery"/> 8 <el-input v-model="queryParams.code" placeholder="请输入商品编码" clearable @keyup.enter.native="handleQuery"/>
10 </el-form-item> 9 </el-form-item>
11 -  
12 <el-form-item label="商品分类" prop="categoryIds"> 10 <el-form-item label="商品分类" prop="categoryIds">
13 <el-cascader v-model="queryParams.categoryIds" placeholder="请输入商品分类" 11 <el-cascader v-model="queryParams.categoryIds" placeholder="请输入商品分类"
14 :options="categoryList" :props="propName" clearable ref="category"/> 12 :options="categoryList" :props="propName" clearable ref="category"/>
15 </el-form-item> 13 </el-form-item>
16 -  
17 <el-form-item label="商品品牌" prop="brandId"> 14 <el-form-item label="商品品牌" prop="brandId">
18 <el-select v-model="queryParams.brandId" placeholder="请输入商品品牌" clearable @keyup.enter.native="handleQuery"> 15 <el-select v-model="queryParams.brandId" placeholder="请输入商品品牌" clearable @keyup.enter.native="handleQuery">
19 <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"/> 16 <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"/>
20 </el-select> 17 </el-select>
21 </el-form-item> 18 </el-form-item>
22 - 19 + <!-- TODO 待实现:商品类型 -->
  20 + <!-- TODO 待实现:商品标签 -->
  21 + <!-- TODO 待实现:营销活动 -->
  22 + <!-- TODO 前端优化:商品销量、商品价格,排的整齐一点 -->
23 <el-form-item label="商品销量"> 23 <el-form-item label="商品销量">
24 - <el-col  
25 - :span="6"  
26 - style="padding-left:0"  
27 - > 24 + <el-col :span="7" style="padding-left:0">
28 <el-form-item prop="salesCountMin"> 25 <el-form-item prop="salesCountMin">
29 - <el-input v-model="queryParams.salesCountMin" placeholder="最小值" clearable  
30 - @keyup.enter.native="handleQuery"/> 26 + <el-input v-model="queryParams.salesCountMin" placeholder="最低销量" clearable @keyup.enter.native="handleQuery"/>
31 </el-form-item> 27 </el-form-item>
32 </el-col> 28 </el-col>
33 - <el-col  
34 - :span="1"  
35 - >  
36 - -  
37 - </el-col>  
38 - <el-col  
39 - :span="6"  
40 - style="padding-left:0"  
41 - > 29 + <el-col :span="1">-</el-col>
  30 + <el-col :span="7" style="padding-left:0">
42 <el-form-item prop="salesCountMax"> 31 <el-form-item prop="salesCountMax">
43 - <el-input v-model="queryParams.salesCountMax" placeholder="最大值" clearable  
44 - @keyup.enter.native="handleQuery"/> 32 + <el-input v-model="queryParams.salesCountMax" placeholder="最高销量" clearable @keyup.enter.native="handleQuery"/>
45 </el-form-item> 33 </el-form-item>
46 </el-col> 34 </el-col>
47 </el-form-item> 35 </el-form-item>
48 -  
49 <el-form-item label="商品价格" prop="code"> 36 <el-form-item label="商品价格" prop="code">
50 - <el-col  
51 - :span="6"  
52 - style="padding-left:0"  
53 - > 37 + <el-col :span="7" style="padding-left:0">
54 <el-form-item prop="marketPriceMin"> 38 <el-form-item prop="marketPriceMin">
55 - <el-input v-model="queryParams.marketPriceMin" placeholder="最小值" clearable  
56 - @keyup.enter.native="handleQuery"/> 39 + <el-input v-model="queryParams.marketPriceMin" placeholder="最低价格" clearable @keyup.enter.native="handleQuery"/>
57 </el-form-item> 40 </el-form-item>
58 </el-col> 41 </el-col>
59 - <el-col  
60 - :span="1"  
61 - >  
62 - -  
63 - </el-col>  
64 - <el-col  
65 - :span="6"  
66 - style="padding-left:0"  
67 - > 42 + <el-col :span="1">-</el-col>
  43 + <el-col :span="7" style="padding-left:0">
68 <el-form-item prop="marketPriceMax"> 44 <el-form-item prop="marketPriceMax">
69 - <el-input v-model="queryParams.marketPriceMax" placeholder="最大值" clearable  
70 - @keyup.enter.native="handleQuery"/> 45 + <el-input v-model="queryParams.marketPriceMax" placeholder="最高价格" clearable @keyup.enter.native="handleQuery"/>
71 </el-form-item> 46 </el-form-item>
72 </el-col> 47 </el-col>
73 </el-form-item> 48 </el-form-item>
74 -  
75 <el-form-item> 49 <el-form-item>
76 <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> 50 <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
77 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> 51 <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
@@ -82,8 +56,7 @@ @@ -82,8 +56,7 @@
82 <el-row :gutter="10" class="mb8"> 56 <el-row :gutter="10" class="mb8">
83 <el-col :span="1.5"> 57 <el-col :span="1.5">
84 <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" 58 <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
85 - v-hasPermi="['product:spu:create']">新增  
86 - </el-button> 59 + v-hasPermi="['product:spu:create']">添加商品</el-button>
87 </el-col> 60 </el-col>
88 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"/> 61 <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"/>
89 </el-row> 62 </el-row>
@@ -96,17 +69,13 @@ @@ -96,17 +69,13 @@
96 <el-table-column label="商品信息" align="center" width="260"> 69 <el-table-column label="商品信息" align="center" width="260">
97 <template slot-scope="scope"> 70 <template slot-scope="scope">
98 <div class="product-info"> 71 <div class="product-info">
99 - <img  
100 - v-if="scope.row.picUrls"  
101 - :src="scope.row.picUrls[0]"  
102 - alt="分类图片"  
103 - class="img-height"  
104 - /> 72 + <img v-if="scope.row.picUrls" :src="scope.row.picUrls[0]" alt="分类图片" class="img-height" />
105 <div class="message">{{ scope.row.name }}</div> 73 <div class="message">{{ scope.row.name }}</div>
106 </div> 74 </div>
107 </template> 75 </template>
  76 + <!-- TODO 前端优化:可以有个 + 号,点击后,展示每个 sku -->
108 </el-table-column> 77 </el-table-column>
109 - <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> 78 + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="formatPrice"/>
110 <el-table-column label="库存" align="center" prop="totalStock"/> 79 <el-table-column label="库存" align="center" prop="totalStock"/>
111 <el-table-column label="销量" align="center" prop="salesCount"/> 80 <el-table-column label="销量" align="center" prop="salesCount"/>
112 <el-table-column label="排序" align="center" prop="sort"/> 81 <el-table-column label="排序" align="center" prop="sort"/>
@@ -117,18 +86,15 @@ @@ -117,18 +86,15 @@
117 </el-table-column> 86 </el-table-column>
118 <el-table-column label="状态" align="center" prop="status"> 87 <el-table-column label="状态" align="center" prop="status">
119 <template slot-scope="scope"> 88 <template slot-scope="scope">
120 - <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> 89 + <dict-tag :type="DICT_TYPE.PRODUCT_SPU_STATUS" :value="scope.row.status"/>
121 </template> 90 </template>
122 </el-table-column> 91 </el-table-column>
123 -  
124 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 92 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
125 <template slot-scope="scope"> 93 <template slot-scope="scope">
126 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" 94 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
127 - v-hasPermi="['product:spu:update']">修改  
128 - </el-button> 95 + v-hasPermi="['product:spu:update']">修改</el-button>
129 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" 96 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
130 - v-hasPermi="['product:spu:delete']">删除  
131 - </el-button> 97 + v-hasPermi="['product:spu:delete']">删除</el-button>
132 </template> 98 </template>
133 </el-table-column> 99 </el-table-column>
134 </el-table> 100 </el-table>
@@ -141,17 +107,12 @@ @@ -141,17 +107,12 @@
141 <el-table-column label="商品信息" align="center" width="260"> 107 <el-table-column label="商品信息" align="center" width="260">
142 <template slot-scope="scope"> 108 <template slot-scope="scope">
143 <div class="product-info"> 109 <div class="product-info">
144 - <img  
145 - v-if="scope.row.picUrls"  
146 - :src="scope.row.picUrls[0]"  
147 - alt="分类图片"  
148 - class="img-height"  
149 - /> 110 + <img v-if="scope.row.picUrls" :src="scope.row.picUrls[0]" alt="分类图片" class="img-height"/>
150 <div class="message">{{ scope.row.name }}</div> 111 <div class="message">{{ scope.row.name }}</div>
151 </div> 112 </div>
152 </template> 113 </template>
153 </el-table-column> 114 </el-table-column>
154 - <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> 115 + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="formatPrice"/>
155 <el-table-column label="库存" align="center" prop="totalStock"/> 116 <el-table-column label="库存" align="center" prop="totalStock"/>
156 <el-table-column label="销量" align="center" prop="salesCount"/> 117 <el-table-column label="销量" align="center" prop="salesCount"/>
157 <el-table-column label="排序" align="center" prop="sort"/> 118 <el-table-column label="排序" align="center" prop="sort"/>
@@ -162,18 +123,15 @@ @@ -162,18 +123,15 @@
162 </el-table-column> 123 </el-table-column>
163 <el-table-column label="状态" align="center" prop="status"> 124 <el-table-column label="状态" align="center" prop="status">
164 <template slot-scope="scope"> 125 <template slot-scope="scope">
165 - <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> 126 + <dict-tag :type="DICT_TYPE.PRODUCT_SPU_STATUS" :value="scope.row.status"/>
166 </template> 127 </template>
167 </el-table-column> 128 </el-table-column>
168 -  
169 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 129 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
170 <template slot-scope="scope"> 130 <template slot-scope="scope">
171 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" 131 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
172 - v-hasPermi="['product:spu:update']">修改  
173 - </el-button> 132 + v-hasPermi="['product:spu:update']">修改</el-button>
174 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" 133 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
175 - v-hasPermi="['product:spu:delete']">删除  
176 - </el-button> 134 + v-hasPermi="['product:spu:delete']">删除</el-button>
177 </template> 135 </template>
178 </el-table-column> 136 </el-table-column>
179 </el-table> 137 </el-table>
@@ -186,17 +144,12 @@ @@ -186,17 +144,12 @@
186 <el-table-column label="商品信息" align="center" width="260"> 144 <el-table-column label="商品信息" align="center" width="260">
187 <template slot-scope="scope"> 145 <template slot-scope="scope">
188 <div class="product-info"> 146 <div class="product-info">
189 - <img  
190 - v-if="scope.row.picUrls"  
191 - :src="scope.row.picUrls[0]"  
192 - alt="分类图片"  
193 - class="img-height"  
194 - /> 147 + <img v-if="scope.row.picUrls" :src="scope.row.picUrls[0]" alt="分类图片" class="img-height"/>
195 <div class="message">{{ scope.row.name }}</div> 148 <div class="message">{{ scope.row.name }}</div>
196 </div> 149 </div>
197 </template> 150 </template>
198 </el-table-column> 151 </el-table-column>
199 - <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> 152 + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="formatPrice"/>
200 <el-table-column label="库存" align="center" prop="totalStock"/> 153 <el-table-column label="库存" align="center" prop="totalStock"/>
201 <el-table-column label="销量" align="center" prop="salesCount"/> 154 <el-table-column label="销量" align="center" prop="salesCount"/>
202 <el-table-column label="排序" align="center" prop="sort"/> 155 <el-table-column label="排序" align="center" prop="sort"/>
@@ -207,18 +160,15 @@ @@ -207,18 +160,15 @@
207 </el-table-column> 160 </el-table-column>
208 <el-table-column label="状态" align="center" prop="status"> 161 <el-table-column label="状态" align="center" prop="status">
209 <template slot-scope="scope"> 162 <template slot-scope="scope">
210 - <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> 163 + <dict-tag :type="DICT_TYPE.PRODUCT_SPU_STATUS" :value="scope.row.status"/>
211 </template> 164 </template>
212 </el-table-column> 165 </el-table-column>
213 -  
214 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 166 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
215 <template slot-scope="scope"> 167 <template slot-scope="scope">
216 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" 168 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
217 - v-hasPermi="['product:spu:update']">修改  
218 - </el-button> 169 + v-hasPermi="['product:spu:update']">修改</el-button>
219 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" 170 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
220 - v-hasPermi="['product:spu:delete']">删除  
221 - </el-button> 171 + v-hasPermi="['product:spu:delete']">删除</el-button>
222 </template> 172 </template>
223 </el-table-column> 173 </el-table-column>
224 </el-table> 174 </el-table>
@@ -231,17 +181,12 @@ @@ -231,17 +181,12 @@
231 <el-table-column label="商品信息" align="center" width="260"> 181 <el-table-column label="商品信息" align="center" width="260">
232 <template slot-scope="scope"> 182 <template slot-scope="scope">
233 <div class="product-info"> 183 <div class="product-info">
234 - <img  
235 - v-if="scope.row.picUrls"  
236 - :src="scope.row.picUrls[0]"  
237 - alt="分类图片"  
238 - class="img-height"  
239 - /> 184 + <img v-if="scope.row.picUrls" :src="scope.row.picUrls[0]" alt="分类图片" class="img-height"/>
240 <div class="message">{{ scope.row.name }}</div> 185 <div class="message">{{ scope.row.name }}</div>
241 </div> 186 </div>
242 </template> 187 </template>
243 </el-table-column> 188 </el-table-column>
244 - <el-table-column label="价格" align="center" prop="marketPrice" :formatter="unitConversion"/> 189 + <el-table-column label="价格" align="center" prop="marketPrice" :formatter="formatPrice"/>
245 <el-table-column label="库存" align="center" prop="totalStock"/> 190 <el-table-column label="库存" align="center" prop="totalStock"/>
246 <el-table-column label="销量" align="center" prop="salesCount"/> 191 <el-table-column label="销量" align="center" prop="salesCount"/>
247 <el-table-column label="排序" align="center" prop="sort"/> 192 <el-table-column label="排序" align="center" prop="sort"/>
@@ -252,27 +197,24 @@ @@ -252,27 +197,24 @@
252 </el-table-column> 197 </el-table-column>
253 <el-table-column label="状态" align="center" prop="status"> 198 <el-table-column label="状态" align="center" prop="status">
254 <template slot-scope="scope"> 199 <template slot-scope="scope">
255 - <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status"/> 200 + <dict-tag :type="DICT_TYPE.PRODUCT_SPU_STATUS" :value="scope.row.status"/>
256 </template> 201 </template>
257 </el-table-column> 202 </el-table-column>
258 -  
259 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 203 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
260 <template slot-scope="scope"> 204 <template slot-scope="scope">
261 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" 205 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
262 - v-hasPermi="['product:spu:update']">修改  
263 - </el-button> 206 + v-hasPermi="['product:spu:update']">修改</el-button>
264 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" 207 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
265 - v-hasPermi="['product:spu:delete']">删除  
266 - </el-button> 208 + v-hasPermi="['product:spu:delete']">删除</el-button>
267 </template> 209 </template>
268 </el-table-column> 210 </el-table-column>
269 </el-table> 211 </el-table>
270 </el-tab-pane> 212 </el-tab-pane>
271 </el-tabs> 213 </el-tabs>
  214 +
272 <!-- 分页组件 --> 215 <!-- 分页组件 -->
273 <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" 216 <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
274 @pagination="getList"/> 217 @pagination="getList"/>
275 -  
276 </div> 218 </div>
277 </template> 219 </template>
278 220
@@ -280,6 +222,7 @@ @@ -280,6 +222,7 @@
280 import {deleteSpu, getSpuPage,} from "@/api/mall/product/spu"; 222 import {deleteSpu, getSpuPage,} from "@/api/mall/product/spu";
281 import {getProductCategoryList} from "@/api/mall/product/category"; 223 import {getProductCategoryList} from "@/api/mall/product/category";
282 import {getBrandList} from "@/api/mall/product/brand"; 224 import {getBrandList} from "@/api/mall/product/brand";
  225 +import {ProductSpuStatusEnum} from "@/utils/constants";
283 226
284 export default { 227 export default {
285 name: "Spu", 228 name: "Spu",
@@ -318,7 +261,6 @@ export default { @@ -318,7 +261,6 @@ export default {
318 salesCountMax: null, 261 salesCountMax: null,
319 marketPriceMin: null, 262 marketPriceMin: null,
320 marketPriceMax: null, 263 marketPriceMax: null,
321 - tabStatus: null,  
322 }, 264 },
323 }; 265 };
324 }, 266 },
@@ -353,9 +295,6 @@ export default { @@ -353,9 +295,6 @@ export default {
353 this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime"); 295 this.addBeginAndEndTime(params, this.dateRangeCreateTime, "createTime");
354 // 执行查询 296 // 执行查询
355 getSpuPage(params).then((response) => { 297 getSpuPage(params).then((response) => {
356 - response.data.list.forEach(element => {  
357 - element.price = this.divide(element.minPrice, 100) + "~" + this.divide(element.maxPrice, 100)  
358 - });  
359 this.list = response.data.list; 298 this.list = response.data.list;
360 this.total = response.data.total; 299 this.total = response.data.total;
361 this.loading = false; 300 this.loading = false;
@@ -390,29 +329,29 @@ export default { @@ -390,29 +329,29 @@ export default {
390 .confirm('是否确认删除商品spu编号为"' + id + '"的数据项?') 329 .confirm('是否确认删除商品spu编号为"' + id + '"的数据项?')
391 .then(function () { 330 .then(function () {
392 return deleteSpu(id); 331 return deleteSpu(id);
393 - })  
394 - .then(() => { 332 + }).then(() => {
395 this.getList(); 333 this.getList();
396 this.$modal.msgSuccess("删除成功"); 334 this.$modal.msgSuccess("删除成功");
397 - })  
398 - .catch(() => { 335 + }).catch(() => {
399 }); 336 });
400 }, 337 },
401 - unitConversion(row, column, cellValue) {  
402 - return this.divide(cellValue, 100); 338 + formatPrice(row, column, cellValue) {
  339 + return '¥' + this.divide(cellValue, 100);
403 }, 340 },
404 - // 选中tab 341 + // 选中 tab
405 handleClick(val) { 342 handleClick(val) {
406 if (val.name === "all") { 343 if (val.name === "all") {
407 - this.queryParams.tabStatus = null; 344 + this.queryParams.status = undefined;
  345 + this.queryParams.alarmStock = undefined;
408 } else if (val.name === "on") { 346 } else if (val.name === "on") {
409 - this.queryParams.tabStatus = 0; 347 + this.queryParams.status = ProductSpuStatusEnum.ENABLE.status;
  348 + this.queryParams.alarmStock = undefined;
410 } else if (val.name === "off") { 349 } else if (val.name === "off") {
411 - this.queryParams.tabStatus = 1; 350 + this.queryParams.status = ProductSpuStatusEnum.DISABLE.status;
  351 + this.queryParams.alarmStock = undefined;
412 } else if (val.name === "remind") { 352 } else if (val.name === "remind") {
413 - this.queryParams.tabStatus = 2;  
414 - } else {  
415 - this.queryParams.tabStatus = null; 353 + this.queryParams.status = undefined;
  354 + this.queryParams.alarmStock = true;
416 } 355 }
417 this.getList(); 356 this.getList();
418 } 357 }
yudao-ui-admin/src/views/mall/product/spu/save.vue
@@ -7,8 +7,8 @@ @@ -7,8 +7,8 @@
7 <el-form-item label="商品名称" prop="name"> 7 <el-form-item label="商品名称" prop="name">
8 <el-input v-model="baseForm.name" placeholder="请输入商品名称"/> 8 <el-input v-model="baseForm.name" placeholder="请输入商品名称"/>
9 </el-form-item> 9 </el-form-item>
10 - <el-form-item label="商品卖点">  
11 - <el-input type="textarea" v-model="baseForm.sellPoint" placeholder="请输入商品卖点"/> 10 + <el-form-item label="促销语">
  11 + <el-input type="textarea" v-model="baseForm.sellPoint" placeholder="请输入促销语"/>
12 </el-form-item> 12 </el-form-item>
13 <el-form-item label="商品主图" prop="picUrls"> 13 <el-form-item label="商品主图" prop="picUrls">
14 <ImageUpload v-model="baseForm.picUrls" :value="baseForm.picUrls" :limit="10" class="mall-image"/> 14 <ImageUpload v-model="baseForm.picUrls" :value="baseForm.picUrls" :limit="10" class="mall-image"/>