mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-29 18:51:53 +08:00
Merge remote-tracking branch 'origin/feature/1.8.0-uniapp' into feature/1.8.0-uniapp
This commit is contained in:
commit
3b506006dd
@ -12,6 +12,6 @@ public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO
|
|||||||
|
|
||||||
@ApiModelProperty(value = "主键", required = true, example = "1024")
|
@ApiModelProperty(value = "主键", required = true, example = "1024")
|
||||||
@NotNull(message = "主键不能为空")
|
@NotNull(message = "主键不能为空")
|
||||||
private Integer id;
|
private Long id;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,9 +55,8 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @luowenfeng: categoryIds => categoryId,example 也要改下哈
|
@ApiModelProperty(value = "分类 id 数组,一直递归到一级父节点", example = "4")
|
||||||
@ApiModelProperty(value = "分类 id 数组,一直递归到一级父节点", example = "[1,2,4]")
|
private Long categoryId;
|
||||||
private Long categoryIds;
|
|
||||||
|
|
||||||
// TODO @芋艿:在瞅瞅~
|
// TODO @芋艿:在瞅瞅~
|
||||||
@ApiModelProperty(value = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]")
|
@ApiModelProperty(value = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]")
|
||||||
|
@ -25,10 +25,9 @@ public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> {
|
|||||||
.orderByDesc(ProductPropertyDO::getId));
|
.orderByDesc(ProductPropertyDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @luowenfeng: selectByNameLike,这样更清晰哈。
|
|
||||||
default ProductPropertyDO selectByName(String name) {
|
default ProductPropertyDO selectByName(String name) {
|
||||||
return selectOne(new LambdaQueryWrapperX<ProductPropertyDO>()
|
return selectOne(new LambdaQueryWrapperX<ProductPropertyDO>()
|
||||||
.likeIfPresent(ProductPropertyDO::getName, name));
|
.eqIfPresent(ProductPropertyDO::getName, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,7 @@ import java.util.List;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> {
|
public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> {
|
||||||
|
|
||||||
// TODO @luowenfeng: selectListByPropertyId 是不是就可以啦
|
default List<ProductPropertyValueDO> selectListByPropertyId(List<Long> propertyIds) {
|
||||||
default List<ProductPropertyValueDO> selectListByPropertyValueListByPropertyId(List<Long> propertyIds) {
|
|
||||||
return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>()
|
return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>()
|
||||||
.inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds));
|
.inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds));
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import javax.annotation.Resource;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_EXISTS;
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_EXISTS;
|
||||||
@ -58,8 +59,8 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
|
|||||||
public void updateProperty(ProductPropertyUpdateReqVO updateReqVO) {
|
public void updateProperty(ProductPropertyUpdateReqVO updateReqVO) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
this.validatePropertyExists(updateReqVO.getId());
|
this.validatePropertyExists(updateReqVO.getId());
|
||||||
// TODO @luowenfeng:如果是自己的情况下,名字相同也是 ok 的呀~
|
ProductPropertyDO productPropertyDO = productPropertyMapper.selectByName(updateReqVO.getName());
|
||||||
if (productPropertyMapper.selectByName(updateReqVO.getName()) != null) {
|
if (productPropertyDO != null && !productPropertyDO.getId().equals(updateReqVO.getId())) {
|
||||||
throw exception(PROPERTY_EXISTS);
|
throw exception(PROPERTY_EXISTS);
|
||||||
}
|
}
|
||||||
// 更新
|
// 更新
|
||||||
@ -97,10 +98,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
|
|||||||
return ProductPropertyConvert.INSTANCE.convertPage(pageResult);
|
return ProductPropertyConvert.INSTANCE.convertPage(pageResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) {
|
|
||||||
return productPropertyValueMapper.selectListByPropertyValueListByPropertyId(propertyIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProductPropertyRespVO getProperty(Long id) {
|
public ProductPropertyRespVO getProperty(Long id) {
|
||||||
ProductPropertyDO property = productPropertyMapper.selectById(id);
|
ProductPropertyDO property = productPropertyMapper.selectById(id);
|
||||||
@ -117,7 +114,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
|
|||||||
List<ProductPropertyRespVO> propertyList = getPropertyList(listReqVO);
|
List<ProductPropertyRespVO> propertyList = getPropertyList(listReqVO);
|
||||||
|
|
||||||
// 查询属性值
|
// 查询属性值
|
||||||
List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.selectListByPropertyValueListByPropertyId(CollectionUtils.convertList(propertyList, ProductPropertyRespVO::getId));
|
List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.selectListByPropertyId(CollectionUtils.convertList(propertyList, ProductPropertyRespVO::getId));
|
||||||
Map<Long, List<ProductPropertyValueDO>> valueDOMap = CollectionUtils.convertMultiMap(valueDOList, ProductPropertyValueDO::getPropertyId);
|
Map<Long, List<ProductPropertyValueDO>> valueDOMap = CollectionUtils.convertMultiMap(valueDOList, ProductPropertyValueDO::getPropertyId);
|
||||||
return CollectionUtils.convertList(propertyList, m -> {
|
return CollectionUtils.convertList(propertyList, m -> {
|
||||||
ProductPropertyAndValueRespVO productPropertyAndValueRespVO = ProductPropertyConvert.INSTANCE.convert(m);
|
ProductPropertyAndValueRespVO productPropertyAndValueRespVO = ProductPropertyConvert.INSTANCE.convert(m);
|
||||||
|
@ -14,6 +14,7 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS;
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS;
|
||||||
@ -42,8 +43,8 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) {
|
public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) {
|
||||||
// TODO @luowenfeng:如果是自己的情况下,名字相同也是 ok 的呀~
|
ProductPropertyValueDO productPropertyValueDO = productPropertyValueMapper.selectByName(updateReqVO.getPropertyId(), updateReqVO.getName());
|
||||||
if (productPropertyValueMapper.selectByName(updateReqVO.getPropertyId(), updateReqVO.getName()) != null) {
|
if (productPropertyValueDO != null && !productPropertyValueDO.getId().equals(updateReqVO.getId())) {
|
||||||
throw exception(PROPERTY_VALUE_EXISTS);
|
throw exception(PROPERTY_VALUE_EXISTS);
|
||||||
}
|
}
|
||||||
ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO);
|
ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO);
|
||||||
|
@ -162,7 +162,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
});
|
});
|
||||||
respVO.setProductPropertyViews(productPropertyViews);
|
respVO.setProductPropertyViews(productPropertyViews);
|
||||||
}
|
}
|
||||||
respVO.setCategoryIds(respVO.getCategoryId());
|
|
||||||
}
|
}
|
||||||
return respVO;
|
return respVO;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.product.service.spu;
|
package cn.iocoder.yudao.module.product.service.spu;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
|
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
|
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
|
||||||
@ -33,10 +36,12 @@ import java.util.*;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
|
|
||||||
// TODO @芋艿:review 下单元测试
|
// TODO @芋艿:review 下单元测试
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ProductSpuServiceImpl} 的单元测试类
|
* {@link ProductSpuServiceImpl} 的单元测试类
|
||||||
*
|
*
|
||||||
@ -67,6 +72,13 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
|||||||
@MockBean
|
@MockBean
|
||||||
private ProductPropertyValueService productPropertyValueService;
|
private ProductPropertyValueService productPropertyValueService;
|
||||||
|
|
||||||
|
public String generateNo() {
|
||||||
|
return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long generateId() {
|
||||||
|
return RandomUtil.randomLong(100000, 999999);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateSpu_success() {
|
public void testCreateSpu_success() {
|
||||||
@ -206,34 +218,119 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
|||||||
Assertions.assertIterableEquals(createReqVO, spuList);
|
Assertions.assertIterableEquals(createReqVO, spuList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @luowenfeng:单测要分情况;类似你这个,可以分 2 个单测;一个是有预存预警的;一个是没库存预警的;
|
|
||||||
// 然后,参考其它模块的 getPage 类型的方法的单测。
|
|
||||||
@Test
|
@Test
|
||||||
void getSpuPage() {
|
void getSpuPage_alarmStock_empty() {
|
||||||
// 准备参数
|
|
||||||
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class);
|
|
||||||
productSpuMapper.insert(createReqVO);
|
|
||||||
|
|
||||||
ArrayList<ProductSkuDO> remindSpuIds = Lists.newArrayList(
|
|
||||||
// randomPojo(ProductSkuDO.class, o -> o.setSpuId(createReqVO.getId())),
|
|
||||||
// randomPojo(ProductSkuDO.class, o -> o.setSpuId(createReqVO.getId()))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Mockito.when(productSkuService.getRemindSpuIds()).thenReturn(remindSpuIds);
|
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
|
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
|
||||||
// productSpuPageReqVO.setTabStatus(2);
|
productSpuPageReqVO.setAlarmStock(true);
|
||||||
|
|
||||||
PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||||
|
|
||||||
Set<Long> resultRemindSpuIds = new HashSet<>();
|
PageResult<Object> result = PageResult.empty();
|
||||||
resultRemindSpuIds.add(null);
|
|
||||||
PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, resultRemindSpuIds));
|
|
||||||
Assertions.assertIterableEquals(result.getList(), spuPage.getList());
|
Assertions.assertIterableEquals(result.getList(), spuPage.getList());
|
||||||
Assertions.assertEquals(spuPage.getTotal(), result.getTotal());
|
Assertions.assertEquals(spuPage.getTotal(), result.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSpuPage_alarmStock() {
|
||||||
|
// mock 数据
|
||||||
|
Long brandId = generateId();
|
||||||
|
Long categoryId = generateId();
|
||||||
|
String code = generateNo();
|
||||||
|
|
||||||
|
// 准备参数
|
||||||
|
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{
|
||||||
|
o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus());
|
||||||
|
o.setTotalStock(500);
|
||||||
|
o.setMinPrice(1);
|
||||||
|
o.setMaxPrice(50);
|
||||||
|
o.setMarketPrice(25);
|
||||||
|
o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType());
|
||||||
|
o.setBrandId(brandId);
|
||||||
|
o.setCategoryId(categoryId);
|
||||||
|
o.setClickCount(100);
|
||||||
|
o.setCode(code);
|
||||||
|
o.setDescription("测试商品");
|
||||||
|
o.setPicUrls(new ArrayList<>());
|
||||||
|
o.setName("测试");
|
||||||
|
o.setSalesCount(100);
|
||||||
|
o.setSellPoint("超级加倍");
|
||||||
|
o.setShowStock(true);
|
||||||
|
o.setVideoUrl("");
|
||||||
|
});
|
||||||
|
productSpuMapper.insert(createReqVO);
|
||||||
|
|
||||||
|
Set<Long> alarmStockSpuIds = SetUtils.asSet(createReqVO.getId());
|
||||||
|
|
||||||
|
List<ProductSkuDO> productSpuDOS = Arrays.asList(randomPojo(ProductSkuDO.class, o -> {
|
||||||
|
o.setSpuId(createReqVO.getId());
|
||||||
|
}), randomPojo(ProductSkuDO.class, o -> {
|
||||||
|
o.setSpuId(createReqVO.getId());
|
||||||
|
}));
|
||||||
|
|
||||||
|
Mockito.when(productSkuService.getSkusByAlarmStock()).thenReturn(productSpuDOS);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
|
||||||
|
productSpuPageReqVO.setAlarmStock(true);
|
||||||
|
PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||||
|
|
||||||
|
PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds));
|
||||||
|
Assertions.assertIterableEquals(result.getList(), spuPage.getList());
|
||||||
|
Assertions.assertEquals(spuPage.getTotal(), result.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getSpuPage() {
|
||||||
|
// mock 数据
|
||||||
|
Long brandId = generateId();
|
||||||
|
Long categoryId = generateId();
|
||||||
|
|
||||||
|
// 准备参数
|
||||||
|
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{
|
||||||
|
o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus());
|
||||||
|
o.setTotalStock(1);
|
||||||
|
o.setMinPrice(1);
|
||||||
|
o.setMaxPrice(1);
|
||||||
|
o.setMarketPrice(1);
|
||||||
|
o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType());
|
||||||
|
o.setBrandId(brandId);
|
||||||
|
o.setCategoryId(categoryId);
|
||||||
|
o.setClickCount(1);
|
||||||
|
o.setCode(generateNo());
|
||||||
|
o.setDescription("测试商品");
|
||||||
|
o.setPicUrls(new ArrayList<>());
|
||||||
|
o.setName("测试");
|
||||||
|
o.setSalesCount(1);
|
||||||
|
o.setSellPoint("卖点");
|
||||||
|
o.setShowStock(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 准备参数
|
||||||
|
productSpuMapper.insert(createReqVO);
|
||||||
|
// 测试 status 不匹配
|
||||||
|
productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus())));
|
||||||
|
productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setStatus(ProductSpuStatusEnum.RECYCLE.getStatus())));
|
||||||
|
// 测试 SpecType 不匹配
|
||||||
|
productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType())));
|
||||||
|
// 测试 BrandId 不匹配
|
||||||
|
productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setBrandId(generateId())));
|
||||||
|
// 测试 CategoryId 不匹配
|
||||||
|
productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setCategoryId(generateId())));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
|
||||||
|
productSpuPageReqVO.setAlarmStock(false);
|
||||||
|
productSpuPageReqVO.setBrandId(brandId);
|
||||||
|
productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus());
|
||||||
|
productSpuPageReqVO.setCategoryId(categoryId);
|
||||||
|
|
||||||
|
PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||||
|
|
||||||
|
PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set<Long>) null));
|
||||||
|
Assertions.assertEquals(result, spuPage);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetSpuPage() {
|
void testGetSpuPage() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
@ -242,13 +339,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
|||||||
});
|
});
|
||||||
productSpuMapper.insert(createReqVO);
|
productSpuMapper.insert(createReqVO);
|
||||||
|
|
||||||
ArrayList<ProductSkuDO> remindSpuIds = Lists.newArrayList(
|
|
||||||
// randomPojo(ProductSkuDO.class, o -> o.setSpuId(createReqVO.getId())),
|
|
||||||
// randomPojo(ProductSkuDO.class, o -> o.setSpuId(createReqVO.getId()))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Mockito.when(productSkuService.getRemindSpuIds()).thenReturn(remindSpuIds);
|
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
AppSpuPageReqVO appSpuPageReqVO = new AppSpuPageReqVO();
|
AppSpuPageReqVO appSpuPageReqVO = new AppSpuPageReqVO();
|
||||||
appSpuPageReqVO.setCategoryId(2L);
|
appSpuPageReqVO.setCategoryId(2L);
|
||||||
|
@ -196,6 +196,21 @@ export const constantRoutes = [
|
|||||||
meta: {title: '流程详情', activeMenu: '/bpm/task/my'}
|
meta: {title: '流程详情', activeMenu: '/bpm/task/my'}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/order',
|
||||||
|
component: Layout,
|
||||||
|
name: '订单管理',
|
||||||
|
meta: { title: '订单管理' },
|
||||||
|
alwaysShow: true,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/order/goods-order',
|
||||||
|
name: '商品订单',
|
||||||
|
meta: { title: '商品订单' },
|
||||||
|
component: (resolve) => require(['@/views/order/goodsOrder'], resolve)
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ export default {
|
|||||||
this.baseForm.id = data.id;
|
this.baseForm.id = data.id;
|
||||||
this.baseForm.name = data.name;
|
this.baseForm.name = data.name;
|
||||||
this.baseForm.sellPoint = data.sellPoint;
|
this.baseForm.sellPoint = data.sellPoint;
|
||||||
this.baseForm.categoryIds = data.categoryIds;
|
this.baseForm.categoryIds = data.categoryId;
|
||||||
this.baseForm.videoUrl = data.videoUrl;
|
this.baseForm.videoUrl = data.videoUrl;
|
||||||
this.baseForm.sort = data.sort;
|
this.baseForm.sort = data.sort;
|
||||||
this.baseForm.description = data.description;
|
this.baseForm.description = data.description;
|
||||||
|
458
yudao-ui-admin/src/views/order/goodsOrder/index.vue
Normal file
458
yudao-ui-admin/src/views/order/goodsOrder/index.vue
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-form
|
||||||
|
:model="queryParams"
|
||||||
|
label-width="68px"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<el-col :span="6" :xs="24">
|
||||||
|
<el-form-item label="搜索方式">
|
||||||
|
<el-input style="width: 240px">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.searchType"
|
||||||
|
slot="prepend"
|
||||||
|
clearable
|
||||||
|
style="width: 100px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dicData.searchType"
|
||||||
|
v-bind="dict"
|
||||||
|
:key="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6" :xs="24">
|
||||||
|
<el-form-item label="订单类型">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.orderType"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dicData.orderType"
|
||||||
|
v-bind="dict"
|
||||||
|
:key="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6" :xs="24">
|
||||||
|
<el-form-item label="订单状态">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.orderStatus"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dicData.orderStatus"
|
||||||
|
v-bind="dict"
|
||||||
|
:key="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6" :xs="24">
|
||||||
|
<el-form-item label="订单来源">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.orderSource"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dicData.orderSource"
|
||||||
|
v-bind="dict"
|
||||||
|
:key="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6" :xs="24">
|
||||||
|
<el-form-item label="付款方式">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.payWay"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dicData.payWay"
|
||||||
|
v-bind="dict"
|
||||||
|
:key="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6" :xs="24">
|
||||||
|
<el-form-item label="营销类型">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.marketingType"
|
||||||
|
clearable
|
||||||
|
style="width: 240px"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="dict in dicData.marketingType"
|
||||||
|
v-bind="dict"
|
||||||
|
:key="dict.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6" :xs="24">
|
||||||
|
<el-form-item label="下单时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.date"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:picker-options="rangePickerOptions"
|
||||||
|
style="width: 240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6" :xs="24" style="line-height: 32px">
|
||||||
|
<el-button type="primary" icon="el-icon-search" size="mini">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" size="mini">重置</el-button>
|
||||||
|
<el-button icon="el-icon-document" size="mini">导出订单</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-form>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-radio-group v-model="activeTabName">
|
||||||
|
<el-radio-button
|
||||||
|
v-for="tabPane in tabPanes"
|
||||||
|
:label="tabPane.label"
|
||||||
|
>{{tabPane.text}}</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
:data="tableData"
|
||||||
|
:span-method="spanMethod"
|
||||||
|
:row-class-name="rowClassName"
|
||||||
|
border
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" :selectable="(row, index) => index % 2"/>
|
||||||
|
<el-table-column label="商品" prop="goods" width="360">
|
||||||
|
<template slot-scope="{ row, $index }">
|
||||||
|
<el-row
|
||||||
|
v-if="$index % 2 === 0"
|
||||||
|
class="card-header"
|
||||||
|
>
|
||||||
|
<el-col :span="5">
|
||||||
|
订单号:{{row.orderNo}}
|
||||||
|
<el-popover
|
||||||
|
title="支付流水号:"
|
||||||
|
:content="row.payNo"
|
||||||
|
ref="popover"
|
||||||
|
placement="right"
|
||||||
|
width="200"
|
||||||
|
trigger="click"
|
||||||
|
/>
|
||||||
|
<el-button type="text" v-popover:popover>
|
||||||
|
更多
|
||||||
|
</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">下单时间:{{row.time}}</el-col>
|
||||||
|
<el-col :span="5">订单来源:{{row.orderSource}}</el-col>
|
||||||
|
<el-col :span="5">支付方式:{{row.payWay}}</el-col>
|
||||||
|
<el-col :span="4" align="right">
|
||||||
|
<el-button type="text">打印发货单</el-button>
|
||||||
|
<el-button type="text">详情</el-button>
|
||||||
|
<el-button type="text">备注</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<div v-else class="goods-info">
|
||||||
|
<img :src="row.picture"/>
|
||||||
|
<span class="ellipsis-2">{{row.name}}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="单价(元)/数量" prop="fee" align="center" width="115">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<div>{{row.price}}</div>
|
||||||
|
<div>{{row.count}}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="维权" prop="safeguard" align="center" width="115"/>
|
||||||
|
<el-table-column label="实付金额(元)" prop="amount" align="center" width="115"/>
|
||||||
|
<el-table-column label="买家/收货人" prop="buyer" width="360">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<div>{{row.buyer}}</div>
|
||||||
|
<div>{{row.receiver}}{{row.tel}}</div>
|
||||||
|
<div class="ellipsis-2">{{row.address}}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="配送方式" prop="sendWay" width="115"/>
|
||||||
|
<el-table-column label="交易状态" prop="status"/>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const dicData = {
|
||||||
|
searchType: [
|
||||||
|
{ label: '订单号', value: 'ddh' },
|
||||||
|
{ label: '交易流水号', value: 'jylsh' },
|
||||||
|
{ label: '订单备注', value: 'ddbz' },
|
||||||
|
{ label: '收货人姓名', value: 'shrxm' },
|
||||||
|
{ label: '商品名称', value: 'spmc' },
|
||||||
|
{ label: '收货人电话', value: 'shrdh' },
|
||||||
|
{ label: '会员昵称', value: 'hync' },
|
||||||
|
{ label: '商品编号', value: 'spbh' }
|
||||||
|
],
|
||||||
|
orderType: [
|
||||||
|
{ label: '全部', value: 'qb' },
|
||||||
|
{ label: '物流订单', value: 'wldd' },
|
||||||
|
{ label: '自提订单', value: 'ztdd' },
|
||||||
|
{ label: '外卖订单', value: 'wmdd' },
|
||||||
|
{ label: '虚拟订单', value: 'xndd' },
|
||||||
|
{ label: '收银订单', value: 'sydd' }
|
||||||
|
],
|
||||||
|
orderStatus: [
|
||||||
|
{ label: '全部', value: 'qb' },
|
||||||
|
{ label: '待支付', value: 'dzf' },
|
||||||
|
{ label: '待发货', value: 'dfh' },
|
||||||
|
{ label: '已发货', value: 'yfh' },
|
||||||
|
{ label: '已收货', value: 'ysh' },
|
||||||
|
{ label: '已完成', value: 'ywc' },
|
||||||
|
{ label: '已关闭', value: 'ygb' },
|
||||||
|
{ label: '退款中', value: 'tkz' }
|
||||||
|
],
|
||||||
|
orderSource: [
|
||||||
|
{ label: '全部', value: 'qb' },
|
||||||
|
{ label: '微信公众号', value: 'wxgzh' },
|
||||||
|
{ label: '微信小程序', value: 'wxxcx' },
|
||||||
|
{ label: 'PC', value: 'pc' },
|
||||||
|
{ label: 'H5', value: 'h5' },
|
||||||
|
{ label: 'APP', value: 'app' },
|
||||||
|
{ label: '收银台', value: 'syt' },
|
||||||
|
{ label: '代客下单', value: 'dkxd' }
|
||||||
|
],
|
||||||
|
payWay: [
|
||||||
|
{ label: '全部', value: 'qb' },
|
||||||
|
{ label: '在线支付', value: 'zxzf' },
|
||||||
|
{ label: '余额支付', value: 'yezf' },
|
||||||
|
{ label: '线下支付', value: 'xxzf' },
|
||||||
|
{ label: '积分兑换', value: 'jfdh' },
|
||||||
|
{ label: '支付宝支付', value: 'zfbzf' },
|
||||||
|
{ label: '微信支付', value: 'wxzf' }
|
||||||
|
],
|
||||||
|
marketingType: [
|
||||||
|
{ label: '全部', value: 'qb' },
|
||||||
|
{ label: '一口价', value: 'ykj' },
|
||||||
|
{ label: '专题', value: 'zt' },
|
||||||
|
{ label: '团购', value: 'tg' },
|
||||||
|
{ label: '拼团', value: 'pt' },
|
||||||
|
{ label: '拼团返利', value: 'ptfl' },
|
||||||
|
{ label: '盲盒', value: 'mh' },
|
||||||
|
{ label: '砍价', value: 'kj' },
|
||||||
|
{ label: '礼品卡优惠', value: 'lpkyh' },
|
||||||
|
{ label: '秒杀', value: 'ms' },
|
||||||
|
{ label: '积分兑换', value: 'jfdh' },
|
||||||
|
{ label: '组合套餐', value: 'zhtc' },
|
||||||
|
{ label: '预售', value: 'ys' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
const rangePickerOptions = {
|
||||||
|
shortcuts: [{
|
||||||
|
text: '最近一周',
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
||||||
|
picker.$emit('pick', [start, end]);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: '最近一个月',
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||||||
|
picker.$emit('pick', [start, end]);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: '最近三个月',
|
||||||
|
onClick(picker) {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
||||||
|
picker.$emit('pick', [start, end]);
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: "index",
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
dicData,
|
||||||
|
rangePickerOptions,
|
||||||
|
queryParams: {
|
||||||
|
searchType: 'ddh',
|
||||||
|
orderType: ''
|
||||||
|
},
|
||||||
|
activeTabName: 'all',
|
||||||
|
tabPanes: [
|
||||||
|
{ text: '全部', label: 'all' },
|
||||||
|
{ text: '待支付', label: 'toBePay' },
|
||||||
|
{ text: '待发货', label: 'toBeSend' },
|
||||||
|
{ text: '已发货', label: 'send' },
|
||||||
|
{ text: '已收货', label: 'received' },
|
||||||
|
{ text: '已完成', label: 'finished' },
|
||||||
|
{ text: '已关闭', label: 'closed' },
|
||||||
|
{ text: '退款中', label: 'refund' }
|
||||||
|
],
|
||||||
|
tableData: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
orderNo: '20221026220424001',
|
||||||
|
payNo: '20221026220424001',
|
||||||
|
time: '2022-10-26 22:04:20',
|
||||||
|
orderSource: 'PC',
|
||||||
|
payWay: '微信支付',
|
||||||
|
name: '颜衫短袖男polo衫夏季翻领衣服潮牌休闲上衣夏天翻领半袖男士t恤',
|
||||||
|
picture: 'https://b2c-v5-yanshi.oss-cn-hangzhou.aliyuncs.com/upload/1/common/images/20220723/20220723115621165854858145027_SMALL.webp',
|
||||||
|
price: '199',
|
||||||
|
count: '5件',
|
||||||
|
amount: 460,
|
||||||
|
safeguard: '主动退款',
|
||||||
|
buyer: '小明',
|
||||||
|
receiver: '小花',
|
||||||
|
tel: '15823655095',
|
||||||
|
address: '北京市-北京市-东城区 观音桥',
|
||||||
|
sendWay: '物流配送',
|
||||||
|
status: '已完成'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
orderNo: '20221026220424001',
|
||||||
|
payNo: '20221026220424001',
|
||||||
|
time: '2022-10-26 22:04:20',
|
||||||
|
orderSource: 'PC',
|
||||||
|
payWay: '微信支付',
|
||||||
|
name: '颜衫短袖男polo衫夏季翻领衣服潮牌休闲上衣夏天翻领半袖男士t恤',
|
||||||
|
picture: 'https://b2c-v5-yanshi.oss-cn-hangzhou.aliyuncs.com/upload/1/common/images/20220723/20220723115621165854858145027_SMALL.webp',
|
||||||
|
price: '199',
|
||||||
|
count: '5件',
|
||||||
|
amount: 460,
|
||||||
|
safeguard: '主动退款',
|
||||||
|
buyer: '小明',
|
||||||
|
receiver: '小花',
|
||||||
|
tel: '15823655095',
|
||||||
|
address: '北京市-北京市-东城区 观音桥',
|
||||||
|
sendWay: '物流配送',
|
||||||
|
status: '已完成'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
orderNo: '20221026220424001',
|
||||||
|
payNo: '20221026220424001',
|
||||||
|
time: '2022-10-26 22:04:20',
|
||||||
|
orderSource: 'PC',
|
||||||
|
payWay: '微信支付',
|
||||||
|
name: '颜衫短袖男polo衫夏季翻领衣服潮牌休闲上衣夏天翻领半袖男士t恤',
|
||||||
|
picture: 'https://b2c-v5-yanshi.oss-cn-hangzhou.aliyuncs.com/upload/1/common/images/20220723/20220723115621165854858145027_SMALL.webp',
|
||||||
|
price: '199',
|
||||||
|
count: '5件',
|
||||||
|
amount: 460,
|
||||||
|
safeguard: '主动退款',
|
||||||
|
buyer: '小明',
|
||||||
|
receiver: '小花',
|
||||||
|
tel: '15823655095',
|
||||||
|
address: '北京市-北京市-东城区 观音桥',
|
||||||
|
sendWay: '物流配送',
|
||||||
|
status: '已完成'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
orderNo: '20221026220424001',
|
||||||
|
payNo: '20221026220424001',
|
||||||
|
time: '2022-10-26 22:04:20',
|
||||||
|
orderSource: 'PC',
|
||||||
|
payWay: '微信支付',
|
||||||
|
name: '颜衫短袖男polo衫夏季翻领衣服潮牌休闲上衣夏天翻领半袖男士t恤',
|
||||||
|
picture: 'https://b2c-v5-yanshi.oss-cn-hangzhou.aliyuncs.com/upload/1/common/images/20220723/20220723115621165854858145027_SMALL.webp',
|
||||||
|
price: '199',
|
||||||
|
count: '5件',
|
||||||
|
amount: 460,
|
||||||
|
safeguard: '主动退款',
|
||||||
|
buyer: '小明',
|
||||||
|
receiver: '小花',
|
||||||
|
tel: '15823655095',
|
||||||
|
address: '北京市-北京市-东城区 观音桥',
|
||||||
|
sendWay: '物流配送',
|
||||||
|
status: '已完成'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
data.forEach((record, index) => {
|
||||||
|
data.splice(index, 0, record)
|
||||||
|
})
|
||||||
|
this.tableData = data
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
spanMethod ({ row, column, rowIndex, columnIndex }) {
|
||||||
|
if (rowIndex % 2 === 0) {
|
||||||
|
if (columnIndex === 1) {
|
||||||
|
return [1, 8]
|
||||||
|
} else {
|
||||||
|
return [0, 0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rowClassName ({ rowIndex }) {
|
||||||
|
if (rowIndex % 2 === 0) {
|
||||||
|
return 'even-row'
|
||||||
|
} else {
|
||||||
|
return 'odd-row'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep .el-table {
|
||||||
|
margin-top: 20px;
|
||||||
|
.el-table__row{
|
||||||
|
&.even-row{
|
||||||
|
>.el-table__cell{
|
||||||
|
padding: 0;
|
||||||
|
.cell{
|
||||||
|
padding: 0;
|
||||||
|
.card-header{
|
||||||
|
padding: 0 10px;
|
||||||
|
line-height: 44px;
|
||||||
|
background: #f7f7f7;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>.el-table__cell{
|
||||||
|
.goods-info{
|
||||||
|
display: flex;
|
||||||
|
img{
|
||||||
|
margin-right: 10px;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border: 1px solid #e2e2e2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ellipsis-2{
|
||||||
|
display: -webkit-box;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: normal;
|
||||||
|
-webkit-line-clamp: 2; /* 要显示的行数 */
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
word-break: break-all;
|
||||||
|
line-height: 22px !important;
|
||||||
|
max-height: 44px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user