|
|
|
@ -32,7 +32,7 @@ import java.util.List;
|
|
|
|
|
*/
|
|
|
|
|
@Service
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class ProductServiceImpl implements IProductService{
|
|
|
|
|
public class ProductServiceImpl implements IProductService {
|
|
|
|
|
@Autowired
|
|
|
|
|
private ProductMapper productMapper;
|
|
|
|
|
@Autowired
|
|
|
|
@ -44,10 +44,10 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse list(int pageNum, int pageSize) {
|
|
|
|
|
//1.pagehelper对下一行取出的集合进行分页
|
|
|
|
|
PageHelper.startPage(pageNum,pageSize);
|
|
|
|
|
PageHelper.startPage(pageNum, pageSize);
|
|
|
|
|
List<Product> productList = productMapper.selectList();
|
|
|
|
|
List<ProductListVo> productListVoList = Lists.newArrayList();
|
|
|
|
|
for(Product product:productList){
|
|
|
|
|
for (Product product : productList) {
|
|
|
|
|
ProductListVo productListVo = assembleProductListVo(product);
|
|
|
|
|
productListVoList.add(productListVo);
|
|
|
|
|
}
|
|
|
|
@ -60,15 +60,15 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse<PageInfo> search(String productName, Integer productId, int pageNum, int pageSize) {
|
|
|
|
|
//开始准备分页
|
|
|
|
|
PageHelper.startPage(pageNum,pageSize);
|
|
|
|
|
PageHelper.startPage(pageNum, pageSize);
|
|
|
|
|
//如果有内容,可以先在这里封装好,直接传到sql中去
|
|
|
|
|
if(StringUtils.isNotBlank(productName)){
|
|
|
|
|
if (StringUtils.isNotBlank(productName)) {
|
|
|
|
|
productName = new StringBuilder().append("%").append(productName).append("%").toString();
|
|
|
|
|
}
|
|
|
|
|
List<Product> productList = productMapper.selectProductByNameAndId(productName,productId);
|
|
|
|
|
List<Product> productList = productMapper.selectProductByNameAndId(productName, productId);
|
|
|
|
|
//转换一下传给前端显示
|
|
|
|
|
List<ProductListVo> productListVoList = Lists.newArrayList();
|
|
|
|
|
for(Product product:productList){
|
|
|
|
|
for (Product product : productList) {
|
|
|
|
|
ProductListVo productListVo = assembleProductListVo(product);
|
|
|
|
|
productListVoList.add(productListVo);
|
|
|
|
|
}
|
|
|
|
@ -80,12 +80,12 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse<ProductDetailVo> detail(Integer productId) {
|
|
|
|
|
//1,校验参数
|
|
|
|
|
if(productId == null){
|
|
|
|
|
if (productId == null) {
|
|
|
|
|
throw new SnailmallException("参数不正确");
|
|
|
|
|
}
|
|
|
|
|
//1-在售 2-下架 3-删除
|
|
|
|
|
Product product = productMapper.selectByPrimaryKey(productId);
|
|
|
|
|
if(product == null){
|
|
|
|
|
if (product == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("商品不存在");
|
|
|
|
|
}
|
|
|
|
|
ProductDetailVo productDetailVo = assembleProductDetailVo(product);
|
|
|
|
@ -95,7 +95,7 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse<String> set_sale_status(Integer productId, Integer status) {
|
|
|
|
|
//1.校验参数
|
|
|
|
|
if(productId == null || status == null){
|
|
|
|
|
if (productId == null || status == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("参数不正确");
|
|
|
|
|
}
|
|
|
|
|
//2.更新状态
|
|
|
|
@ -105,8 +105,8 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
//3.删除该商品缓存
|
|
|
|
|
commonCacheUtil.delKey(Constants.PRODUCT_TOKEN_PREFIX);
|
|
|
|
|
int rowCount = productMapper.updateByPrimaryKeySelective(product);
|
|
|
|
|
if(rowCount > 0){
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX+productId,JsonUtil.obj2String(product),Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
if (rowCount > 0) {
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX + productId, JsonUtil.obj2String(product), Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
return ServerResponse.createBySuccessMessage("更新产品状态成功");
|
|
|
|
|
}
|
|
|
|
|
return ServerResponse.createByErrorMessage("更新产品状态失败");
|
|
|
|
@ -115,33 +115,33 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse<String> saveOrUpdateProduct(Product product) {
|
|
|
|
|
//1.校验参数
|
|
|
|
|
if(product == null || product.getCategoryId()==null){
|
|
|
|
|
if (product == null || product.getCategoryId() == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("参数不正确");
|
|
|
|
|
}
|
|
|
|
|
//2.设置一下主图,主图为子图的第一个图
|
|
|
|
|
if(StringUtils.isNotBlank(product.getSubImages())){
|
|
|
|
|
if (StringUtils.isNotBlank(product.getSubImages())) {
|
|
|
|
|
String[] subImages = product.getSubImages().split(",");
|
|
|
|
|
if(subImages.length > 0){
|
|
|
|
|
if (subImages.length > 0) {
|
|
|
|
|
product.setMainImage(subImages[0]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//3.看前端传过来的产品id是否存在,存在则为更新,否则为新增
|
|
|
|
|
if(product.getId() != null){
|
|
|
|
|
if (product.getId() != null) {
|
|
|
|
|
//删除该商品缓存
|
|
|
|
|
commonCacheUtil.delKey(Constants.PRODUCT_TOKEN_PREFIX);
|
|
|
|
|
int rowCount = productMapper.updateByPrimaryKeySelective(product);
|
|
|
|
|
if(rowCount > 0){
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX+product.getId(),JsonUtil.obj2String(product),Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
if (rowCount > 0) {
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX + product.getId(), JsonUtil.obj2String(product), Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
return ServerResponse.createBySuccessMessage("更新产品成功");
|
|
|
|
|
}
|
|
|
|
|
return ServerResponse.createByErrorMessage("更新产品失败");
|
|
|
|
|
}else {
|
|
|
|
|
} else {
|
|
|
|
|
//新增
|
|
|
|
|
product.setCreateTime(new Date());//这两句可能多余,因为xml中已经保证了,就先放这里
|
|
|
|
|
product.setUpdateTime(new Date());
|
|
|
|
|
int rowCount = productMapper.insert(product);
|
|
|
|
|
if(rowCount > 0){
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX+product.getId(),JsonUtil.obj2String(product),Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
if (rowCount > 0) {
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX + product.getId(), JsonUtil.obj2String(product), Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
return ServerResponse.createBySuccessMessage("新增产品成功");
|
|
|
|
|
}
|
|
|
|
|
return ServerResponse.createByErrorMessage("新增产品失败");
|
|
|
|
@ -149,37 +149,62 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现前台门户获取产品详细信息的业务方法,用于根据传入的产品ID查询并返回该产品的详细信息给前台展示,
|
|
|
|
|
* 在查询过程中会进行参数校验、产品是否存在校验以及产品状态校验等操作,只有满足条件的产品才会将其详细信息封装后返回。
|
|
|
|
|
*
|
|
|
|
|
* @param productId 产品的唯一标识符,用于从数据库中精确查询对应的产品详细信息,不能为空,若为空则直接返回参数错误提示信息。
|
|
|
|
|
* @return 返回一个ServerResponse<ProductDetailVo>对象,ServerResponse用于封装响应的整体情况(成功、失败等),
|
|
|
|
|
* 内部泛型ProductDetailVo用于承载产品的详细信息(如名称、价格、库存、状态等),若产品存在且状态正常则包含具体的产品详情数据,若出现参数错误、产品不存在或已下架等情况则包含相应的错误提示信息。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse<ProductDetailVo> getPortalProductDetail(Integer productId) {
|
|
|
|
|
if(productId == null){
|
|
|
|
|
// 首先进行参数校验,判断传入的产品ID是否为null,如果是null,说明传入的参数不正确,不符合获取产品详情的基本要求,
|
|
|
|
|
// 此时直接返回一个ServerResponse对象,其内部封装了表示失败的错误消息“参数不正确”,告知前台调用方参数存在问题。
|
|
|
|
|
if (productId == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("参数不正确");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据传入的产品ID,通过ProductMapper调用数据库查询方法,从数据库中获取对应的产品记录,这里尝试获取产品的完整信息,以便后续进行更多判断和封装返回详情数据。
|
|
|
|
|
Product product = productMapper.selectByPrimaryKey(productId);
|
|
|
|
|
if(product == null){
|
|
|
|
|
|
|
|
|
|
// 判断从数据库中查询到的产品是否为null,如果是null,说明该产品不存在,此时返回一个ServerResponse对象,
|
|
|
|
|
// 其内部封装了表示失败的错误消息“商品不存在”,告知前台调用方所请求查看详情的商品在系统中不存在。
|
|
|
|
|
if (product == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("商品不存在");
|
|
|
|
|
}
|
|
|
|
|
if(product.getStatus() != Constants.Product.PRODUCT_ON){
|
|
|
|
|
|
|
|
|
|
// 进一步校验产品的状态,判断产品的状态是否不等于Constants.Product.PRODUCT_ON(这里Constants.Product.PRODUCT_ON应该是表示产品处于在售状态的一个常量定义),
|
|
|
|
|
// 如果产品状态不符合在售条件,说明产品已下架或被删除等情况,不适合展示详情给前台,此时返回一个ServerResponse对象,
|
|
|
|
|
// 其内部封装了表示失败的错误消息“产品已下架或删除”,告知前台调用方该产品当前不可查看详情。
|
|
|
|
|
if (product.getStatus()!= Constants.Product.PRODUCT_ON) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("产品已下架或删除");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果前面的参数校验、产品存在校验以及产品状态校验都通过,说明该产品符合要求,可以获取并封装其详细信息返回给前台。
|
|
|
|
|
// 通过调用assembleProductDetailVo方法,将从数据库查询到的Product对象转换为ProductDetailVo对象,ProductDetailVo对象包含了更适合前台展示的产品详细信息结构和内容。
|
|
|
|
|
ProductDetailVo productDetailVo = assembleProductDetailVo(product);
|
|
|
|
|
|
|
|
|
|
// 最后返回一个ServerResponse对象,其内部封装了表示成功的状态以及包含产品详细信息的ProductDetailVo对象,告知前台调用方已成功获取到产品详情并返回相应数据,供前台进行展示等操作。
|
|
|
|
|
return ServerResponse.createBySuccess(productDetailVo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse<PageInfo> portalList(String keyword, Integer categoryId, String orderBy, int pageNum, int pageSize) {
|
|
|
|
|
//准备盛放categoryIds
|
|
|
|
|
List<Integer> categoryIdList = Lists.newArrayList();
|
|
|
|
|
//如果categoryId不为空
|
|
|
|
|
if(categoryId != null){
|
|
|
|
|
if (categoryId != null) {
|
|
|
|
|
//对于这里,直接强转出错了,所以我就序列化处理了一下
|
|
|
|
|
ServerResponse response = categoryClient.getCategoryDetail(categoryId);
|
|
|
|
|
Object object = response.getData();
|
|
|
|
|
String objStr = JsonUtil.obj2String(object);
|
|
|
|
|
Category category = JsonUtil.Str2Obj(objStr,Category.class);
|
|
|
|
|
if(category == null && StringUtils.isBlank(keyword)){
|
|
|
|
|
Category category = JsonUtil.Str2Obj(objStr, Category.class);
|
|
|
|
|
if (category == null && StringUtils.isBlank(keyword)) {
|
|
|
|
|
////直接返回空
|
|
|
|
|
PageHelper.startPage(pageNum,pageSize);
|
|
|
|
|
PageHelper.startPage(pageNum, pageSize);
|
|
|
|
|
List<ProductListVo> productListVoList = Lists.newArrayList();
|
|
|
|
|
PageInfo pageInfo = new PageInfo(productListVoList);
|
|
|
|
|
return ServerResponse.createBySuccess(pageInfo);
|
|
|
|
@ -188,24 +213,24 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
categoryIdList = (List<Integer>) categoryClient.getDeepCategory(categoryId).getData();
|
|
|
|
|
}
|
|
|
|
|
//如果keyword不为空
|
|
|
|
|
if(StringUtils.isNotBlank(keyword)){
|
|
|
|
|
if (StringUtils.isNotBlank(keyword)) {
|
|
|
|
|
keyword = new StringBuilder().append("%").append(keyword).append("%").toString();
|
|
|
|
|
}
|
|
|
|
|
//如果orderBy不为空
|
|
|
|
|
if(StringUtils.isNotBlank(orderBy)){
|
|
|
|
|
if(Constants.ProductListOrderBy.PRICE_ASC_DESC.contains(orderBy)){
|
|
|
|
|
if (StringUtils.isNotBlank(orderBy)) {
|
|
|
|
|
if (Constants.ProductListOrderBy.PRICE_ASC_DESC.contains(orderBy)) {
|
|
|
|
|
String[] orderByArray = orderBy.split("_");
|
|
|
|
|
//特定的格式
|
|
|
|
|
PageHelper.orderBy(orderByArray[0]+" "+orderByArray[1]);
|
|
|
|
|
PageHelper.orderBy(orderByArray[0] + " " + orderByArray[1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
PageHelper.startPage(pageNum,pageSize);
|
|
|
|
|
PageHelper.startPage(pageNum, pageSize);
|
|
|
|
|
//模糊查询
|
|
|
|
|
List<Product> productList = productMapper.selectByNameAndCategoryIds(StringUtils.isBlank(keyword)?null:keyword,
|
|
|
|
|
categoryIdList.size()==0?null:categoryIdList);
|
|
|
|
|
List<Product> productList = productMapper.selectByNameAndCategoryIds(StringUtils.isBlank(keyword) ? null : keyword,
|
|
|
|
|
categoryIdList.size() == 0 ? null : categoryIdList);
|
|
|
|
|
//封装返回对象
|
|
|
|
|
List<ProductListVo> productListVoList = Lists.newArrayList();
|
|
|
|
|
for(Product product : productList){
|
|
|
|
|
for (Product product : productList) {
|
|
|
|
|
ProductListVo productListVo = assembleProductListVo(product);
|
|
|
|
|
productListVoList.add(productListVo);
|
|
|
|
|
}
|
|
|
|
@ -218,96 +243,165 @@ public class ProductServiceImpl implements IProductService{
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse queryProduct(Integer productId) {
|
|
|
|
|
//1.校验参数
|
|
|
|
|
if(productId == null){
|
|
|
|
|
if (productId == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("参数错误");
|
|
|
|
|
}
|
|
|
|
|
//2.去redis中查询,没有则把商品重新添加进redis中
|
|
|
|
|
String redisProductStr = commonCacheUtil.getCacheValue(Constants.PRODUCT_TOKEN_PREFIX+productId);
|
|
|
|
|
if (redisProductStr == null){
|
|
|
|
|
String redisProductStr = commonCacheUtil.getCacheValue(Constants.PRODUCT_TOKEN_PREFIX + productId);
|
|
|
|
|
if (redisProductStr == null) {
|
|
|
|
|
Product product = productMapper.selectByPrimaryKey(productId);
|
|
|
|
|
if(product == null){
|
|
|
|
|
if (product == null) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("商品不存在");
|
|
|
|
|
}
|
|
|
|
|
if(product.getStatus() != Constants.Product.PRODUCT_ON){
|
|
|
|
|
if (product.getStatus() != Constants.Product.PRODUCT_ON) {
|
|
|
|
|
return ServerResponse.createByErrorMessage("商品已经下架或者删除");
|
|
|
|
|
}
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX+productId,JsonUtil.obj2String(product),Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX + productId, JsonUtil.obj2String(product), Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//2.获取商品
|
|
|
|
|
Product product = JsonUtil.Str2Obj(commonCacheUtil.getCacheValue(Constants.PRODUCT_TOKEN_PREFIX+productId),Product.class);
|
|
|
|
|
Product product = JsonUtil.Str2Obj(commonCacheUtil.getCacheValue(Constants.PRODUCT_TOKEN_PREFIX + productId), Product.class);
|
|
|
|
|
return ServerResponse.createBySuccess(product);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 该私有方法用于将Product对象转换为ProductListVo对象,主要提取产品的部分关键属性进行封装,
|
|
|
|
|
* 这些属性是在展示产品列表时所需要的信息,方便后续将整理好的数据传递给前端进行展示。
|
|
|
|
|
*
|
|
|
|
|
* @param product 传入的Product对象,包含了产品的完整信息,从数据库查询等途径获取到的原始产品数据对象。
|
|
|
|
|
* @return 返回一个ProductListVo对象,该对象封装了产品在列表展示场景下所需要展示的相关属性信息。
|
|
|
|
|
*/
|
|
|
|
|
private ProductListVo assembleProductListVo(Product product) {
|
|
|
|
|
// 创建一个ProductListVo对象,用于存放要返回的产品列表展示相关信息,该对象的属性会被逐步设置为从传入的Product对象中提取的对应属性值。
|
|
|
|
|
ProductListVo productListVo = new ProductListVo();
|
|
|
|
|
// 将传入Product对象的ID属性值设置到ProductListVo对象中,这个ID用于唯一标识产品,方便在前端进行相关操作(如点击查看详情等)时能准确关联到对应的产品记录。
|
|
|
|
|
productListVo.setId(product.getId());
|
|
|
|
|
// 将传入Product对象的副标题属性值设置到ProductListVo对象中,副标题可以提供产品的一些补充说明信息,辅助用户更好地了解产品特点等情况,在列表中展示给用户。
|
|
|
|
|
productListVo.setSubtitle(product.getSubtitle());
|
|
|
|
|
// 将传入Product对象的主图片路径或URL属性值设置到ProductListVo对象中,用于在前端列表页面展示产品的主要外观形象,让用户直观看到产品样子。
|
|
|
|
|
productListVo.setMainImage(product.getMainImage());
|
|
|
|
|
// 将传入Product对象的价格属性值设置到ProductListVo对象中,价格是用户关注的重要信息之一,展示给用户了解产品的售卖价格情况。
|
|
|
|
|
productListVo.setPrice(product.getPrice());
|
|
|
|
|
// 将传入Product对象的所属类别ID属性值设置到ProductListVo对象中,通过这个类别ID可以关联到对应的产品分类信息,便于进行分类筛选、查找同类别下的其他产品等操作,在列表展示中体现产品的分类归属。
|
|
|
|
|
productListVo.setCategoryId(product.getCategoryId());
|
|
|
|
|
// 将传入Product对象的名称属性值设置到ProductListVo对象中,产品名称是最直观展示给用户用于区分不同产品的关键信息,在列表中突出显示。
|
|
|
|
|
productListVo.setName(product.getName());
|
|
|
|
|
// 将传入Product对象的状态属性值设置到ProductListVo对象中,产品状态可以表示产品当前是上架(可售卖)、下架(不可售卖)等不同情况,方便用户了解产品的可购买性等状态信息,在列表中展示。
|
|
|
|
|
productListVo.setStatus(product.getStatus());
|
|
|
|
|
productListVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix","http://image.snail.com/"));
|
|
|
|
|
// 通过PropertiesUtil工具类获取图片服务器的HTTP前缀配置信息,如果配置不存在,则使用默认值"http://image.snail.com/",
|
|
|
|
|
// 并将该前缀设置到ProductListVo对象的imageHost属性中,这个属性与产品的图片路径(如mainImage等属性)配合使用,
|
|
|
|
|
// 用于在前端正确拼接出完整的图片访问URL,使得图片能够正常展示出来。
|
|
|
|
|
productListVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix", "http://image.snail.com/"));
|
|
|
|
|
return productListVo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ProductDetailVo assembleProductDetailVo(Product product){
|
|
|
|
|
/**
|
|
|
|
|
* 该私有方法用于将Product对象转换为ProductDetailVo对象,提取产品的详细属性信息进行封装,
|
|
|
|
|
* 这些属性涵盖了产品的各个方面,是在展示产品详细信息时所需要传递给前端的数据,同时还会额外获取产品所属品类的父品类ID信息(通过与品类服务交互)。
|
|
|
|
|
*
|
|
|
|
|
* @param product 传入的Product对象,包含了产品的完整信息,从数据库查询等途径获取到的原始产品数据对象。
|
|
|
|
|
* @return 返回一个ProductDetailVo对象,该对象封装了产品在详情展示场景下所需要展示的丰富的属性信息,包括关联获取的父品类ID等。
|
|
|
|
|
*/
|
|
|
|
|
private ProductDetailVo assembleProductDetailVo(Product product) {
|
|
|
|
|
// 创建一个ProductDetailVo对象,用于存放要返回的产品详细信息,该对象的属性会被逐步设置为从传入的Product对象中提取的对应属性值以及通过其他方式获取的相关信息。
|
|
|
|
|
ProductDetailVo productDetailVo = new ProductDetailVo();
|
|
|
|
|
// 将传入Product对象的ID属性值设置到ProductDetailVo对象中,用于唯一标识产品,方便前端和后端进行与该产品相关的各种操作时准确关联到对应的产品记录。
|
|
|
|
|
productDetailVo.setId(product.getId());
|
|
|
|
|
// 将传入Product对象的副标题属性值设置到ProductDetailVo对象中,副标题可以提供产品的一些补充说明信息,辅助用户更好地了解产品特点等情况,在详情展示中展示给用户。
|
|
|
|
|
productDetailVo.setSubtitle(product.getSubtitle());
|
|
|
|
|
// 将传入Product对象的主图片路径或URL属性值设置到ProductDetailVo对象中,用于在前端详情页面展示产品的主要外观形象,让用户直观看到产品样子。
|
|
|
|
|
productDetailVo.setMainImage(product.getMainImage());
|
|
|
|
|
// 将传入Product对象的子图片路径或URL集合(通常以某种格式拼接存储)属性值设置到ProductDetailVo对象中,用于展示产品的其他相关图片,从不同角度或者展示不同细节等,丰富用户对产品外观等方面的了解,在详情展示中体现。
|
|
|
|
|
productDetailVo.setSubImages(product.getSubImages());
|
|
|
|
|
// 将传入Product对象的价格属性值设置到ProductDetailVo对象中,价格是用户关注的重要信息之一,展示给用户了解产品的售卖价格情况。
|
|
|
|
|
productDetailVo.setPrice(product.getPrice());
|
|
|
|
|
// 将传入Product对象的所属类别ID属性值设置到ProductDetailVo对象中,通过这个类别ID可以关联到对应的产品分类信息,便于进行分类相关的综合查询、导航等操作,在详情展示中体现产品的分类归属。
|
|
|
|
|
productDetailVo.setCategoryId(product.getCategoryId());
|
|
|
|
|
// 将传入Product对象的详细描述信息属性值设置到ProductDetailVo对象中,产品的详细描述包含了产品的功能、参数、使用方法、注意事项等详细内容,用于用户全面深入地了解产品的各种特性,在详情展示中完整呈现给用户。
|
|
|
|
|
productDetailVo.setDetail(product.getDetail());
|
|
|
|
|
// 将传入Product对象的名称属性值设置到ProductDetailVo对象中,产品名称是最直观展示给用户用于区分不同产品的关键信息,在详情展示中突出显示。
|
|
|
|
|
productDetailVo.setName(product.getName());
|
|
|
|
|
// 将传入Product对象的状态属性值设置到ProductDetailVo对象中,产品状态可以表示产品当前是上架(可售卖)、下架(不可售卖)等不同情况,方便用户了解产品的可购买性等状态信息,在详情展示中展示。
|
|
|
|
|
productDetailVo.setStatus(product.getStatus());
|
|
|
|
|
// 将传入Product对象的库存数量属性值设置到ProductDetailVo对象中,库存数量用于记录当前产品还有多少可售卖的数量,用户可以据此了解产品的供货情况,在详情展示中展示给用户。
|
|
|
|
|
productDetailVo.setStock(product.getStock());
|
|
|
|
|
// 通过PropertiesUtil工具类获取图片服务器的HTTP前缀配置信息,如果配置不存在,则使用默认值"http://image.snail.com/",
|
|
|
|
|
// 并将该前缀设置到ProductDetailVo对象的imageHost属性中,这个属性与产品的图片路径(如mainImage、subImages等属性)配合使用,
|
|
|
|
|
// 用于在前端正确拼接出完整的图片访问URL,使得图片能够正常展示出来。
|
|
|
|
|
productDetailVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix", "http://image.snail.com/"));
|
|
|
|
|
|
|
|
|
|
productDetailVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix","http://image.snail.com/"));
|
|
|
|
|
//返回给前端还需要一下该商品所处品类的父品类id,所以需要去品类服务中去查询一下,这里就要用到Feign
|
|
|
|
|
if(categoryClient.getCategoryDetail(product.getCategoryId()).isSuccess()){
|
|
|
|
|
// 返回给前端还需要产品所处品类的父品类ID信息,所以需要通过品类客户端(categoryClient,通常基于Feign等方式实现与其他服务通信)去品类服务中查询该信息。
|
|
|
|
|
if (categoryClient.getCategoryDetail(product.getCategoryId()).isSuccess()) {
|
|
|
|
|
// 如果获取品类详情操作成功,获取返回的ServerResponse对象,该对象封装了服务端返回的响应信息,包含了操作是否成功以及具体的数据内容等。
|
|
|
|
|
ServerResponse response = categoryClient.getCategoryDetail(product.getCategoryId());
|
|
|
|
|
// 从ServerResponse对象中获取其携带的数据内容,这个数据应该是与产品所属品类相关的信息,具体类型需要后续转换处理。
|
|
|
|
|
Object object = response.getData();
|
|
|
|
|
// 将获取到的对象数据转换为JSON字符串形式,方便后续进行JSON反序列化操作,将其还原为对应的Java对象。
|
|
|
|
|
String objStr = JsonUtil.obj2String(object);
|
|
|
|
|
Category category = (Category) JsonUtil.Str2Obj(objStr,Category.class);
|
|
|
|
|
// 通过JsonUtil工具类将JSON字符串反序列化为Category对象,该对象包含了产品所属品类的详细信息,如名称、父ID等属性。
|
|
|
|
|
Category category = (Category) JsonUtil.Str2Obj(objStr, Category.class);
|
|
|
|
|
// 将获取到的品类对象的父ID属性值设置到ProductDetailVo对象的parentCategoryId属性中,这样前端就能获取到产品所属品类的父品类ID信息了。
|
|
|
|
|
productDetailVo.setParentCategoryId(category.getParentId());
|
|
|
|
|
}else {
|
|
|
|
|
} else {
|
|
|
|
|
// 如果获取品类详情操作失败,设置ProductDetailVo对象的parentCategoryId属性为默认值0,表示无法获取到有效的父品类ID信息。
|
|
|
|
|
productDetailVo.setParentCategoryId(0);
|
|
|
|
|
}
|
|
|
|
|
// 将传入Product对象的创建时间属性值转换为字符串格式,并设置到ProductDetailVo对象的createTime属性中,创建时间记录产品信息首次被录入系统的时间,以合适的格式展示给前端用户查看产品的历史信息等情况。
|
|
|
|
|
productDetailVo.setCreateTime(DateTimeUtil.dateToStr(product.getCreateTime()));
|
|
|
|
|
// 将传入Product对象的更新时间属性值转换为字符串格式,并设置到ProductDetailVo对象的updateTime属性中,更新时间记录产品信息最后一次被修改的时间,同样以合适的格式展示给前端用户了解产品信息的更新情况。
|
|
|
|
|
productDetailVo.setUpdateTime(DateTimeUtil.dateToStr(product.getUpdateTime()));
|
|
|
|
|
return productDetailVo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现将产品库存信息预置到Redis缓存中的业务方法,通过查询所有产品列表,筛选出状态为在售(Constants.Product.PRODUCT_ON)的产品,
|
|
|
|
|
* 将其产品ID和库存数量以特定的键值对形式缓存到Redis中,缓存设置了过期时间,最后返回表示预置库存成功的ServerResponse对象给调用方。
|
|
|
|
|
*
|
|
|
|
|
* @return 返回一个ServerResponse对象,其内部封装了成功状态以及包含“预置库存成功”提示消息的字符串内容,表示产品库存信息已成功预置到Redis缓存中。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse preInitProductStcokToRedis() {
|
|
|
|
|
// 通过ProductMapper查询获取所有产品的列表信息,返回一个包含所有产品记录的Product类型的List集合。
|
|
|
|
|
List<Product> productList = productMapper.selectList();
|
|
|
|
|
for(Product product:productList){
|
|
|
|
|
// 遍历查询到的每个产品记录,进行如下操作:
|
|
|
|
|
for (Product product : productList) {
|
|
|
|
|
// 获取产品的唯一标识符(ID),用于在缓存中作为键的一部分,以便准确区分不同产品的库存信息缓存。
|
|
|
|
|
Integer productId = product.getId();
|
|
|
|
|
// 获取产品的库存数量,用于缓存到Redis中,方便后续业务逻辑中快速获取产品库存情况。
|
|
|
|
|
Integer stock = product.getStock();
|
|
|
|
|
if(productId != null && stock != null && product.getStatus().equals(Constants.Product.PRODUCT_ON)){
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_STOCK_PREFIX+String.valueOf(productId),String.valueOf(stock),Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
// 判断产品ID、库存数量是否不为null,并且产品状态是否为在售(Constants.Product.PRODUCT_ON),如果满足这些条件,则进行缓存操作。
|
|
|
|
|
if (productId != null && stock != null && product.getStatus().equals(Constants.Product.PRODUCT_ON)) {
|
|
|
|
|
// 通过CommonCacheUtil工具类将产品库存信息缓存到Redis中,设置缓存的键(以Constants.PRODUCT_TOKEN_STOCK_PREFIX + 产品ID的字符串形式为键)、
|
|
|
|
|
// 值(库存数量转换为字符串形式)以及过期时间(Constants.PRODUCT_EXPIRE_TIME),这样后续可以通过该键快速获取产品的库存信息,并且缓存数据会在过期时间后自动失效,保证数据的时效性。
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_STOCK_PREFIX + String.valueOf(productId), String.valueOf(stock), Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ServerResponse.createBySuccessMessage("预置库存成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 实现将产品信息预置到Redis缓存中的业务方法,通过查询所有产品列表,筛选出状态为在售(Constants.Product.PRODUCT_ON)的产品,
|
|
|
|
|
* 将其产品信息以JSON字符串形式缓存到Redis中,缓存设置了过期时间,最后返回表示预置商品信息成功的ServerResponse对象给调用方。
|
|
|
|
|
*
|
|
|
|
|
* @return 返回一个ServerResponse对象,其内部封装了成功状态以及包含“预置商品信息成功”提示消息的字符串内容,表示产品信息已成功预置到Redis缓存中。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public ServerResponse preInitProductListToRedis() {
|
|
|
|
|
// 通过ProductMapper查询获取所有产品的列表信息,返回一个包含所有产品记录的Product类型的List集合。
|
|
|
|
|
List<Product> productList = productMapper.selectList();
|
|
|
|
|
for(Product product:productList){
|
|
|
|
|
// 遍历查询到的每个产品记录,进行如下操作:
|
|
|
|
|
for (Product product : productList) {
|
|
|
|
|
// 获取产品的唯一标识符(ID),用于在缓存中作为键的一部分,以便准确区分不同产品的信息缓存。
|
|
|
|
|
Integer productId = product.getId();
|
|
|
|
|
if(productId != null && product.getStatus().equals(Constants.Product.PRODUCT_ON)){
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX+String.valueOf(productId),JsonUtil.obj2String(product),Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
// 判断产品ID是否不为null,并且产品状态是否为在售(Constants.Product.PRODUCT_ON),如果满足这些条件,则进行缓存操作。
|
|
|
|
|
if (productId != null && product.getStatus().equals(Constants.Product.PRODUCT_ON)) {
|
|
|
|
|
// 通过CommonCacheUtil工具类将产品信息缓存到Redis中,设置缓存的键(以Constants.PRODUCT_TOKEN_PREFIX + 产品ID的字符串形式为键)、
|
|
|
|
|
// 值(将产品对象转换为JSON字符串形式,通过JsonUtil工具类进行转换)以及过期时间(Constants.PRODUCT_EXPIRE_TIME),
|
|
|
|
|
// 这样后续可以通过该键快速获取产品的详细信息,并且缓存数据会在过期时间后自动失效,保证数据的时效性。
|
|
|
|
|
commonCacheUtil.cacheNxExpire(Constants.PRODUCT_TOKEN_PREFIX + String.valueOf(productId), JsonUtil.obj2String(product), Constants.PRODUCT_EXPIRE_TIME);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ServerResponse.createBySuccessMessage("预置商品信息成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|