更新商城前端商品,购物车,订单的价格,后端存储的时候单位分,显示的时候统一转为元

This commit is contained in:
Wang 2026-01-31 14:02:02 +08:00
parent 2344bb2938
commit 6b7ba7258c
8 changed files with 66 additions and 128 deletions

View File

@ -69,6 +69,9 @@ public class MoneyUtil {
* @return 元单位的 double * @return 元单位的 double
*/ */
public static BigDecimal centToYuan(BigDecimal cent) { public static BigDecimal centToYuan(BigDecimal cent) {
if (cent == null ) {
return BigDecimal.ZERO;
}
return NumberUtil.div(cent, 100, 2); return NumberUtil.div(cent, 100, 2);
} }

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seer.teach.common.PageListBean; import com.seer.teach.common.PageListBean;
import com.seer.teach.common.enums.GoodSaleEnum; import com.seer.teach.common.enums.GoodSaleEnum;
import com.seer.teach.common.utils.MoneyUtil;
import com.seer.teach.common.utils.PageConverterUtils; import com.seer.teach.common.utils.PageConverterUtils;
import com.seer.teach.mall.app.good.service.IAppGoodsService; import com.seer.teach.mall.app.good.service.IAppGoodsService;
import com.seer.teach.mall.app.good.service.IAppGoodsSpecificationService; import com.seer.teach.mall.app.good.service.IAppGoodsSpecificationService;
@ -102,9 +103,10 @@ public class AppGoodsServiceImpl implements IAppGoodsService {
item.setBarCode(specification.getBarCode()); item.setBarCode(specification.getBarCode());
item.setPicUrl(specification.getPicUrl()); item.setPicUrl(specification.getPicUrl());
item.setStock(specification.getStock()); item.setStock(specification.getStock());
item.setPrice(specification.getPrice()); item.setPrice(MoneyUtil.centToYuan(specification.getPrice()));
specificationEntityMap.put(key.toString(), item); specificationEntityMap.put(key.toString(), item);
} }
detailResp.setPrice(MoneyUtil.centToYuan(detailResp.getPrice()));
detailResp.setAttributes(itemMap.values()); detailResp.setAttributes(itemMap.values());
detailResp.setSkuItemMap(specificationEntityMap); detailResp.setSkuItemMap(specificationEntityMap);
detailResp.setSalesCount(goodsEntity.getSalesCount() + goodsEntity.getVirtualSellVolume()); detailResp.setSalesCount(goodsEntity.getSalesCount() + goodsEntity.getVirtualSellVolume());

View File

@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.common.PageListBean; import com.seer.teach.common.PageListBean;
import com.seer.teach.common.enums.ResultCodeEnum; import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils; import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.common.utils.MoneyUtil;
import com.seer.teach.common.utils.PageConverterUtils; import com.seer.teach.common.utils.PageConverterUtils;
import com.seer.teach.mall.app.good.service.IAppGoodsSpecificationService; import com.seer.teach.mall.app.good.service.IAppGoodsSpecificationService;
import com.seer.teach.mall.app.order.service.IAppCartService; import com.seer.teach.mall.app.order.service.IAppCartService;
@ -73,7 +74,7 @@ public class AppCartServiceImpl extends ServiceImpl<CartMapper, CartEntity> impl
cartRespPageList.getList().forEach(cartResp -> { cartRespPageList.getList().forEach(cartResp -> {
GoodsSpecificationEntity sku = specificationEntityMap.get(cartResp.getSkuId()); GoodsSpecificationEntity sku = specificationEntityMap.get(cartResp.getSkuId());
cartResp.setPicUrl(sku.getPicUrl()); cartResp.setPicUrl(sku.getPicUrl());
cartResp.setPrice(sku.getPrice()); cartResp.setPrice(MoneyUtil.centToYuan(sku.getPrice()));
cartResp.setAttributeList(sku.getAttributes()); cartResp.setAttributeList(sku.getAttributes());
}); });
return cartRespPageList; return cartRespPageList;

View File

@ -155,7 +155,7 @@ public class AppOrderServiceImpl implements IAppOrderService {
item.setGoodsId(goods.getId()); item.setGoodsId(goods.getId());
BigDecimal price = new BigDecimal(String.valueOf(goodSku.getPrice())).multiply(new BigDecimal(count)); BigDecimal price = new BigDecimal(String.valueOf(goodSku.getPrice())).multiply(new BigDecimal(count));
item.setPrice(price); item.setPrice(MoneyUtil.centToYuan(price));
item.setPicUrl(goodSku.getPicUrl()); item.setPicUrl(goodSku.getPicUrl());
item.setCount(count); item.setCount(count);
item.setSkuId(goodSku.getId()); item.setSkuId(goodSku.getId());
@ -174,7 +174,7 @@ public class AppOrderServiceImpl implements IAppOrderService {
CoinToAmountRespDTO coinToAmountRespDTO = accountServiceApi.convertCoinToAmount(String.valueOf(totalPrices)); CoinToAmountRespDTO coinToAmountRespDTO = accountServiceApi.convertCoinToAmount(String.valueOf(totalPrices));
settlementRespVO.setTotalPrice(new BigDecimal(coinToAmountRespDTO.getAmount())); settlementRespVO.setTotalPrice(new BigDecimal(coinToAmountRespDTO.getAmount()));
} else { } else {
settlementRespVO.setTotalPrice(totalPrices); settlementRespVO.setTotalPrice(MoneyUtil.centToYuan(totalPrices));
} }
log.info("订单结算完成,用户使用[{}]支付的总价格: {}, 总数量: {}", orderSettlementReq.getChannelCode(), totalPrices, totalCount); log.info("订单结算完成,用户使用[{}]支付的总价格: {}, 总数量: {}", orderSettlementReq.getChannelCode(), totalPrices, totalCount);
return settlementRespVO; return settlementRespVO;
@ -280,20 +280,19 @@ public class AppOrderServiceImpl implements IAppOrderService {
} }
Collection<OrderChildEntity> childOrders = new ArrayList<>(); Collection<OrderChildEntity> childOrders = new ArrayList<>();
merchantUserList.forEach((merchantUserId, goodsList) -> { merchantUserList.forEach((merchantUserId, goodsList) -> {
BigDecimal totalCoin = goodsList.stream() BigDecimal totalPrice = goodsList.stream()
.map(goods -> goods.getPrice().multiply(BigDecimal.valueOf(skuCountMapping.getOrDefault(goods.getId(), 1)))) .map(goods -> goods.getPrice().multiply(BigDecimal.valueOf(skuCountMapping.getOrDefault(goods.getId(), 1))))
.reduce(BigDecimal.ZERO, BigDecimal::add); .reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal cnyPrice = getGoodsCnyPrice(totalCoin, coinConfig);
OrderChildEntity childOrder = new OrderChildEntity(); OrderChildEntity childOrder = new OrderChildEntity();
childOrder.setParentOrderId(orderEntity.getId()); childOrder.setParentOrderId(orderEntity.getId());
childOrder.setChildOrderSn(OrderIdGenerator.generateOrderId(OrderIdGenerator.MALL_CHILD_ORDER_PREFIX)); childOrder.setChildOrderSn(OrderIdGenerator.generateOrderId(OrderIdGenerator.MALL_CHILD_ORDER_PREFIX));
childOrder.setUserId(orderEntity.getUserId()); childOrder.setUserId(orderEntity.getUserId());
childOrder.setAddressId(orderEntity.getAddressId()); childOrder.setAddressId(orderEntity.getAddressId());
childOrder.setAddTime(LocalDateTime.now()); childOrder.setAddTime(LocalDateTime.now());
childOrder.setGoodsPrice(cnyPrice); childOrder.setGoodsPrice(totalPrice);
childOrder.setActualPrice(cnyPrice); childOrder.setActualPrice(totalPrice);
childOrder.setOrderPrice(cnyPrice); childOrder.setOrderPrice(totalPrice);
childOrder.setOrderTotalCoin(totalCoin); childOrder.setOrderTotalCoin(getGoodsCnyPrice(totalPrice, coinConfig));
childOrder.setMerchantUserId(merchantUserId); childOrder.setMerchantUserId(merchantUserId);
childOrder.setPayStatus(PayStatusEnum.PENDING.getCode()); childOrder.setPayStatus(PayStatusEnum.PENDING.getCode());
childOrder.setOrderStatus(OrderStatusEnum.PENDING_PAYMENT.getCode()); childOrder.setOrderStatus(OrderStatusEnum.PENDING_PAYMENT.getCode());
@ -346,8 +345,8 @@ public class AppOrderServiceImpl implements IAppOrderService {
orderItem.setGoodsId(spec.getGoodsId()); orderItem.setGoodsId(spec.getGoodsId());
orderItem.setNumber(number); orderItem.setNumber(number);
orderItem.setSkuId(spec.getId()); orderItem.setSkuId(spec.getId());
orderItem.setCoin(spec.getPrice()); orderItem.setCoin(getGoodsCnyPrice(spec.getPrice(), coinConfig));
orderItem.setPrice(getGoodsCnyPrice(spec.getPrice(), coinConfig)); orderItem.setPrice(spec.getPrice());
orderItem.setAttributes(getAttributes(spec.getAttributes())); orderItem.setAttributes(getAttributes(spec.getAttributes()));
orderItem.setGoodsName(goods.getName()); orderItem.setGoodsName(goods.getName());
if (StringUtils.hasText(spec.getPicUrl())) { if (StringUtils.hasText(spec.getPicUrl())) {
@ -441,9 +440,9 @@ public class AppOrderServiceImpl implements IAppOrderService {
BigDecimal itemTotal = spec.getPrice().multiply(BigDecimal.valueOf(number)); BigDecimal itemTotal = spec.getPrice().multiply(BigDecimal.valueOf(number));
goodsTotalPrice = goodsTotalPrice.add(itemTotal); goodsTotalPrice = goodsTotalPrice.add(itemTotal);
} }
BigDecimal orderTotalCoin = goodsTotalPrice; BigDecimal price = goodsTotalPrice;
BigDecimal orderTotalCoin = MoneyUtil.yuanToCentWithBigDecimal(MoneyUtil.convertCoinToAmount(price, coinConfig.getExchangeRatio()));
orderEntity.setOrderTotalCoin(orderTotalCoin); orderEntity.setOrderTotalCoin(orderTotalCoin);
BigDecimal price = MoneyUtil.yuanToCentWithBigDecimal(MoneyUtil.convertCoinToAmount(goodsTotalPrice, coinConfig.getExchangeRatio()));
orderEntity.setGoodsPrice(price); orderEntity.setGoodsPrice(price);
orderEntity.setActualPrice(price); orderEntity.setActualPrice(price);
orderEntity.setOrderPrice(price); orderEntity.setOrderPrice(price);

View File

@ -1,11 +1,14 @@
package com.seer.teach.mall.convert; package com.seer.teach.mall.convert;
import com.seer.teach.common.utils.MoneyUtil;
import com.seer.teach.mall.entity.GoodsEntity; import com.seer.teach.mall.entity.GoodsEntity;
import com.seer.teach.mall.entity.GoodsSpecificationEntity; import com.seer.teach.mall.entity.GoodsSpecificationEntity;
import com.seer.teach.mall.response.*; import com.seer.teach.mall.response.*;
import com.seer.teach.mall.response.GoodSpuDetailResp; import com.seer.teach.mall.response.GoodSpuDetailResp;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.Mapping; import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.List; import java.util.List;
@ -23,5 +26,20 @@ public interface GoodsConvert {
GoodSpuDetailResp one(GoodsEntity goodsEntity); GoodSpuDetailResp one(GoodsEntity goodsEntity);
GoodsResp convertOne(GoodsEntity goodsEntity); GoodsResp convertOne(GoodsEntity goodsEntity);
List<GoodsResp> convertList(List<GoodsEntity> list); List<GoodsResp> convertList(List<GoodsEntity> list);
}
/**
* 在映射完成后将分转换为元
* @param entity 源对象
* @param response 目标对象
*/
@AfterMapping
default void convertCentToYuan(GoodsEntity entity, @MappingTarget GoodsResp response) {
// 将价格从分转换为元
if (entity.getPrice() != null) {
response.setPrice(MoneyUtil.centToYuan(entity.getPrice()));
}
}
}

View File

@ -1,8 +1,13 @@
package com.seer.teach.mall.convert; package com.seer.teach.mall.convert;
import com.seer.teach.common.utils.MoneyUtil;
import com.seer.teach.mall.entity.GoodsSpecificationEntity; import com.seer.teach.mall.entity.GoodsSpecificationEntity;
import com.seer.teach.mall.entity.OrderGoodsEntity;
import com.seer.teach.mall.response.GoodsSpecificationResp; import com.seer.teach.mall.response.GoodsSpecificationResp;
import com.seer.teach.mall.response.OrderItemResp;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.List; import java.util.List;
@ -15,4 +20,24 @@ public interface GoodsSpecificationConvert {
GoodsSpecificationResp toResp(GoodsSpecificationEntity entity); GoodsSpecificationResp toResp(GoodsSpecificationEntity entity);
List<GoodsSpecificationResp> list(List<GoodsSpecificationEntity> goodsSpecificationEntity); List<GoodsSpecificationResp> list(List<GoodsSpecificationEntity> goodsSpecificationEntity);
}
/**
* 在映射完成后将分转换为元
* @param entity 源对象
* @param response 目标对象
*/
@AfterMapping
default void convertCentToYuan(GoodsSpecificationEntity entity, @MappingTarget GoodsSpecificationResp response) {
// 将价格从分转换为元
if (entity.getPrice() != null) {
response.setPrice(MoneyUtil.centToYuan(entity.getPrice()));
}
if (entity.getMarketPrice() != null) {
response.setMarketPrice(MoneyUtil.centToYuan(entity.getMarketPrice()));
}
if (entity.getCostPrice() != null) {
response.setCostPrice(MoneyUtil.centToYuan(entity.getCostPrice()));
}
}
}

View File

@ -35,10 +35,10 @@ public class GoodsSpecificationResp {
private BigDecimal price; private BigDecimal price;
@Schema(name = "市场价", example = "2999") @Schema(name = "市场价", example = "2999")
private Long marketPrice; private BigDecimal marketPrice;
@Schema(name = "成本价", example = "19") @Schema(name = "成本价", example = "19")
private Long costPrice; private BigDecimal costPrice;
@Schema(name = "条形码", example = "11-11-01") @Schema(name = "条形码", example = "11-11-01")
private String barCode; private String barCode;

View File

@ -1,110 +0,0 @@
package com.seer.teach.mp.admin.service.impl;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import com.seer.teach.mp.entity.MpActivityCarouselEntity;
import com.seer.teach.mp.mapper.MpActivityCarouselMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class AdminActivityCarouselServiceImplTest {
@Mock
private MpActivityCarouselMapper mpActivityCarouselMapper;
@InjectMocks
private AdminActivityCarouselServiceImpl adminActivityCarouselService;
private MpActivityCarouselEntity carouselEntity;
@BeforeEach
void setUp() {
carouselEntity = new MpActivityCarouselEntity();
carouselEntity.setId(1);
carouselEntity.setImageUrl("https://example.com/image.jpg");
carouselEntity.setTitle("Test Carousel");
carouselEntity.setActivityId(1);
carouselEntity.setIsActive(true);
carouselEntity.setSortOrder(1);
}
@Test
void testSaveOrUpdateCarousel_Create() {
// Given
when(mpActivityCarouselMapper.insert(any(MpActivityCarouselEntity.class))).thenReturn(1);
com.seer.teach.mp.admin.controller.req.MpActivityCarouselReq request = new com.seer.teach.mp.admin.controller.req.MpActivityCarouselReq();
request.setImageUrl("https://example.com/image.jpg");
request.setTitle("Test Carousel");
request.setActivityId(1);
request.setIsActive(true);
request.setSortOrder(1);
// When
Boolean result = adminActivityCarouselService.saveOrUpdateCarousel(request);
// Then
assertTrue(result);
verify(mpActivityCarouselMapper, times(1)).insert(any(MpActivityCarouselEntity.class));
}
@Test
void testSaveOrUpdateCarousel_Update() {
// Given
when(mpActivityCarouselMapper.selectById(1)).thenReturn(carouselEntity);
when(mpActivityCarouselMapper.updateById(any(MpActivityCarouselEntity.class))).thenReturn(1);
com.seer.teach.mp.admin.controller.req.MpActivityCarouselReq request = new com.seer.teach.mp.admin.controller.req.MpActivityCarouselReq();
request.setId(1);
request.setImageUrl("https://example.com/image.jpg");
request.setTitle("Updated Carousel");
request.setActivityId(1);
request.setIsActive(true);
request.setSortOrder(2);
// When
Boolean result = adminActivityCarouselService.saveOrUpdateCarousel(request);
// Then
assertTrue(result);
verify(mpActivityCarouselMapper, times(1)).selectById(1);
verify(mpActivityCarouselMapper, times(1)).updateById(any(MpActivityCarouselEntity.class));
}
@Test
void testDeleteCarousel() {
// Given
when(mpActivityCarouselMapper.selectById(1)).thenReturn(carouselEntity);
when(mpActivityCarouselMapper.deleteById(1)).thenReturn(1);
// When
Boolean result = adminActivityCarouselService.deleteCarousel(1);
// Then
assertTrue(result);
verify(mpActivityCarouselMapper, times(1)).selectById(1);
verify(mpActivityCarouselMapper, times(1)).deleteById(1);
}
@Test
void testGetById() {
// Given
when(mpActivityCarouselMapper.selectById(1)).thenReturn(carouselEntity);
// When
var result = adminActivityCarouselService.getById(1);
// Then
assertNotNull(result);
assertEquals("Test Carousel", result.getTitle());
assertEquals("https://example.com/image.jpg", result.getImageUrl());
verify(mpActivityCarouselMapper, times(1)).selectById(1);
}
}