Bladeren bron

商品类型(类目),树形结构查询,上传接口完成。

Sakana 3 dagen geleden
bovenliggende
commit
10d086494e

+ 10 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/commodity/ShopCategoryRemoteController.java

@@ -0,0 +1,10 @@
+package edu.travel.remote.commodity;
+
+import edu.travel.remote.base.RemoteBaseController;
+import edu.travel.remote.dto.ShopCategoryDto;
+import edu.travel.remote.vo.ShopCategoryVo;
+import org.springframework.cloud.openfeign.FeignClient;
+
+@FeignClient(name="commodity",path = "/shopCategory")
+public interface ShopCategoryRemoteController extends RemoteBaseController<ShopCategoryVo, ShopCategoryDto> {
+}

+ 2 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/commodity/ShopReviewRemoteController.java

@@ -3,6 +3,8 @@ package edu.travel.remote.commodity;
 import edu.travel.remote.base.RemoteBaseController;
 import edu.travel.remote.dto.ShopReviewDto;
 import edu.travel.remote.vo.ShopReviewVo;
+import org.springframework.cloud.openfeign.FeignClient;
 
+@FeignClient(name="commodity",path = "/shopReview")
 public interface ShopReviewRemoteController extends RemoteBaseController<ShopReviewVo, ShopReviewDto> {
 }

+ 67 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/dto/ShopCategoryDto.java

@@ -0,0 +1,67 @@
+package edu.travel.remote.dto;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import edu.travel.entity.BaseEntity;
+import edu.travel.po.PagePO;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品类型
+ */
+@Data
+public class ShopCategoryDto extends PagePO {
+    /**
+     * 商品类型ID
+     */
+    private Long id;
+
+    /**
+     * 父级分类ID(0表示顶级分类)
+     */
+    private Long parentId;
+    /**
+     * iconID(上传方法返回值)
+     */
+    private String iconId;
+
+    /**
+     * 国家ID
+     */
+    private String countryId;
+
+    /**
+     * 热度值
+     */
+    private Integer heatValue;
+
+    /**
+     * 仓库ID
+     */
+    private Long warehouseId;
+
+    /**
+     * 分类名称
+     */
+    private String typeName;
+
+    /**
+     * 分类图标/封面图
+     */
+    private String imageUrl;
+
+    /**
+     * 排序权重(数值越大越靠前)
+     */
+    private Integer sortOrder;
+
+    /**
+     * 是否启用 0 是 1否
+     */
+    private Integer enable;
+
+}

+ 75 - 0
edu-travel-remote/edu-travel-remote-commodity/src/main/java/edu/travel/remote/vo/ShopCategoryVo.java

@@ -0,0 +1,75 @@
+package edu.travel.remote.vo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import edu.travel.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 商品类型
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName(value = "shop_category")
+public class ShopCategoryVo extends BaseEntity {
+    /**
+     * 商品类型ID
+     */
+    private Long id;
+
+    /**
+     * 父级分类ID(0表示顶级分类)
+     */
+    private Long parentId;
+
+    /**
+     * 国家ID
+     */
+    private String countryId;
+
+    /**
+     * 热度值
+     */
+    private Integer heatValue;
+
+    /**
+     * 仓库ID
+     */
+    private Long warehouseId;
+
+    /**
+     * 分类名称
+     */
+    private String typeName;
+
+    /**
+     * 分类图标/封面图
+     */
+    private String imageUrl;
+
+    /**
+     * 排序权重(数值越大越靠前)
+     */
+    private Integer sortOrder;
+
+    /**
+     * 是否启用 0 是 1否
+     */
+    private Integer enable;
+    /**
+     * 子类
+     */
+    private List<ShopCategoryVo> children;
+    /**
+     * map
+     */
+    private Map<String,Object> map;
+}

+ 4 - 0
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/ShopCategoryService.java

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import edu.travel.remote.dto.BaseDto;
 import edu.travel.remote.dto.ShopTypeDto;
 import edu.travel.remote.vo.ShopTypeVo;
+import edu.travel.rpc.RPCBaseResponse;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 import java.util.concurrent.ExecutionException;
@@ -14,4 +16,6 @@ public interface ShopCategoryService extends IService<ShopCategory>{
     List<ShopTypeVo> getShopType(ShopTypeDto param) throws ExecutionException;
 
     List<ShopTypeVo> getLevelToShopType(BaseDto param) throws ExecutionException;
+
+    RPCBaseResponse<String> uploadIcon(MultipartFile file);
 }

+ 79 - 20
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/impl/ShopCategoryServiceImpl.java

@@ -2,44 +2,62 @@ package edu.travel.commodity.service.impl;
 
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileTypeUtil;
+import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import edu.travel.adapter.service.country.CountryAdapter;
+import edu.travel.adapter.service.upload.UploadAdapter;
 import edu.travel.commodity.constant.BaseConstant;
 import edu.travel.commodity.constant.RedisKey;
 import edu.travel.commodity.entity.ShopCategory;
 import edu.travel.commodity.mapper.ShopCategoryMapper;
 import edu.travel.commodity.service.ShopCategoryService;
+import edu.travel.commodity.utils.FIleUtil;
 import edu.travel.commodity.utils.RedisUtil;
 import edu.travel.remote.dto.BaseDto;
 import edu.travel.remote.dto.ShopTypeDto;
+import edu.travel.remote.upload.dto.EduFileDTO;
 import edu.travel.remote.vo.ShopTypeVo;
+import edu.travel.rpc.RPCBaseResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.View;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+import static edu.travel.rpc.RPCBaseResponse.error;
+import static edu.travel.rpc.RPCBaseResponse.success;
+
 @Service
 public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, ShopCategory> implements ShopCategoryService {
     @Autowired
     private RedisUtil redisUtil;
+    @Autowired
+    private UploadAdapter uploadAdapter;
+    @Autowired
+    private CountryAdapter countryAdapter;
 
     @Override
     public List<ShopTypeVo> getShopType(ShopTypeDto shopTypeDto) {
-        String redisKey="";
-        if(shopTypeDto.getIsHeat().equals(BaseConstant.BASIC_STATUS_NO_STR)){
-            redisKey=RedisKey.PRODUCT_HOT_TYPE;
-        }else {
-            redisKey=RedisKey.PRODUCT_TYPE;
+        String redisKey = "";
+        if (shopTypeDto.getIsHeat().equals(BaseConstant.BASIC_STATUS_NO_STR)) {
+            redisKey = RedisKey.PRODUCT_HOT_TYPE;
+        } else {
+            redisKey = RedisKey.PRODUCT_TYPE;
         }
-        String string = redisUtil.getString(redisKey+shopTypeDto.getCountryId());
-        if(!ObjectUtil.isEmpty(string)){
+        String string = redisUtil.getString(redisKey + shopTypeDto.getCountryId());
+        if (!ObjectUtil.isEmpty(string)) {
             JSONArray objects = JSONUtil.parseArray(string);
             return JSONUtil.toList(objects, ShopTypeVo.class);
         }
@@ -47,18 +65,18 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
         //条件构建
         query.eq(ShopCategory::getCountryId, shopTypeDto.getCountryId());
 
-        if(shopTypeDto.getIsHeat().equals(BaseConstant.BASIC_STATUS_NO_STR)){
+        if (shopTypeDto.getIsHeat().equals(BaseConstant.BASIC_STATUS_NO_STR)) {
             query.orderByDesc(ShopCategory::getHeatValue);
-        }else {
+        } else {
             query.orderByDesc(ShopCategory::getSortOrder);
         }
         List<ShopCategory> list = list(query);
-        if(list.isEmpty()){
+        if (list.isEmpty()) {
             return new ArrayList<>();
         }
         //父级
         List<ShopCategory> collect = list.stream().filter(item -> item.getParentId().equals(0L)).collect(Collectors.toList());
-        if(collect.isEmpty()){
+        if (collect.isEmpty()) {
             return new ArrayList<>();
         }
         List<ShopTypeVo> parent = BeanUtil.copyToList(collect, ShopTypeVo.class);
@@ -67,33 +85,74 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
             List<ShopTypeVo> shopTypeVos = BeanUtil.copyToList(children, ShopTypeVo.class);
             shopCategory.setChildren(shopTypeVos);
         }
-        if(shopTypeDto.getIsHeat().equals(BaseConstant.BASIC_STATUS_NO_STR)){
+        if (shopTypeDto.getIsHeat().equals(BaseConstant.BASIC_STATUS_NO_STR)) {
             //24小时热门过期
-            redisUtil.setString(RedisKey.PRODUCT_HOT_TYPE+shopTypeDto.getCountryId(),JSONUtil.toJsonStr(parent),24*60*60*60, TimeUnit.SECONDS);
-        }else {
-            redisUtil.setString(RedisKey.PRODUCT_TYPE+shopTypeDto.getCountryId(),JSONUtil.toJsonStr(parent));
+            redisUtil.setString(RedisKey.PRODUCT_HOT_TYPE + shopTypeDto.getCountryId(), JSONUtil.toJsonStr(parent), 24 * 60 * 60 * 60, TimeUnit.SECONDS);
+        } else {
+            redisUtil.setString(RedisKey.PRODUCT_TYPE + shopTypeDto.getCountryId(), JSONUtil.toJsonStr(parent));
         }
         return parent;
     }
 
     @Override
     public List<ShopTypeVo> getLevelToShopType(BaseDto param) {
-        String string = redisUtil.getString(RedisKey.PRODUCT_TO_HOT_TYPE+param.getCountryId());
-        if(!ObjectUtil.isEmpty(string)){
+        String string = redisUtil.getString(RedisKey.PRODUCT_TO_HOT_TYPE + param.getCountryId());
+        if (!ObjectUtil.isEmpty(string)) {
             JSONArray objects = JSONUtil.parseArray(string);
             return JSONUtil.toList(objects, ShopTypeVo.class);
         }
         LambdaQueryWrapper<ShopCategory> query = Wrappers.lambdaQuery();
         //条件构建
         query.eq(ShopCategory::getCountryId, param.getCountryId())
-                .orderByDesc(ShopCategory::getHeatValue).ne(ShopCategory::getParentId,0);
+                .orderByDesc(ShopCategory::getHeatValue).ne(ShopCategory::getParentId, 0);
         List<ShopCategory> list = list(query);
-        if(list.isEmpty()){
+        if (list.isEmpty()) {
             return new ArrayList<>();
         }
         List<ShopTypeVo> parent = BeanUtil.copyToList(list, ShopTypeVo.class);
         //24小时热门过期
-        redisUtil.setString(RedisKey.PRODUCT_TO_HOT_TYPE+param.getCountryId(),JSONUtil.toJsonStr(parent),24*60*60*60, TimeUnit.SECONDS);
+        redisUtil.setString(RedisKey.PRODUCT_TO_HOT_TYPE + param.getCountryId(), JSONUtil.toJsonStr(parent), 24 * 60 * 60 * 60, TimeUnit.SECONDS);
         return parent;
     }
+
+    //上传商品类型icon
+    @Override
+    public RPCBaseResponse<String> uploadIcon(MultipartFile file) {
+        //判断上传的文件是否为空或未选择
+        if (file == null || file.isEmpty()) {
+            return error();
+        }
+        try {
+            //获取文件类型
+            String fileType = FileTypeUtil.getType(file.getInputStream());
+            //检查文件类型是否有效且是否在允许的评论图片类型列表中
+            if (fileType != null && BaseConstant.getReviewImageTypes().contains(fileType.toLowerCase())) {
+                //获取用户上传的文件名
+                String filename = file.getOriginalFilename();
+                //检查文件名是否为空
+                if (ObjectUtil.isEmpty(filename)) {
+                    return error();
+                }
+                //初始化上传,获取上传 ID
+                RPCBaseResponse<String> stringRPCBaseResponse = uploadAdapter.initializeUpload();
+                //创建文件 DTO 对象,用于存储文件相关信息
+                EduFileDTO eduFileDTO = new EduFileDTO();
+                eduFileDTO.setUploadId(stringRPCBaseResponse.getData());
+                eduFileDTO.setFileType(fileType);
+                eduFileDTO.setFileName(filename);
+                //生成系统文件名
+                eduFileDTO.setFileSysName(IdUtil.fastSimpleUUID() + DateUtil.format(new Date(), "yyyyMMddHHmmss") + "." + fileType);
+                //计算文件的 MD5 值以便后续验证
+                eduFileDTO.setFileMd5(FIleUtil.calculateFileMd5(file.getBytes()));
+                //调用上传适配器进行文件上传
+                RPCBaseResponse<?> rpcBaseResponse = uploadAdapter.uploadFile(eduFileDTO, file);
+               // 返回成功响应,包含上传后的数据
+                return success(rpcBaseResponse.getData().toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return error("file upload fail");
+        }
+        return error();
+    }
 }

+ 6 - 0
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/service/impl/ShopReviewServiceImpl.java

@@ -184,6 +184,12 @@ public class ShopReviewServiceImpl extends ServiceImpl<ShopReviewMapper, ShopRev
         }
         return error();
     }
+
+    /**
+     * 上传多张图片
+     * @param files
+     * @return
+     */
     public RPCBaseResponse<String> uploadReviewImages(List<MultipartFile> files) {
         // 判断上传的文件列表是否为空或未选择
         if (files == null || files.isEmpty()) {

+ 178 - 13
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/web/ShopCategoryController.java

@@ -1,39 +1,55 @@
 package edu.travel.commodity.web;
 
+import edu.travel.adapter.service.country.CountryAdapter;
+import edu.travel.adapter.service.upload.UploadAdapter;
 import edu.travel.commodity.entity.ShopCategory;
 import edu.travel.commodity.service.ShopCategoryService;
+import edu.travel.remote.commodity.ShopCategoryRemoteController;
 import edu.travel.remote.dto.BaseDto;
+import edu.travel.remote.dto.ShopCategoryDto;
 import edu.travel.remote.dto.ShopTypeDto;
 import edu.travel.remote.feign.mode.vo.tenant.AddMenuVo;
+import edu.travel.remote.vo.ShopCategoryVo;
+import edu.travel.remote.vo.ShopTypeVo;
 import edu.travel.resp.BaseResponse;
 import edu.travel.rpc.RPCBaseResponse;
-import edu.travel.remote.vo.ShopTypeVo;
+import edu.travel.vo.BaseCountryServeVo;
+import edu.travel.vo.BaseCountryVo;
 import edu.travel.web.BaseController;
-import org.springframework.web.bind.annotation.*;
-
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutionException;
 
 import static edu.travel.rpc.RPCBaseResponse.success;
 
 /**
-* 商品类型(shop_category)表控制层
-*
-* @author xxxxx
-*/
+ * 商品类型(shop_category)表控制层
+ *
+ * @author xxxxx
+ */
 @RestController
 @RequestMapping("/shopCategory")
-public class ShopCategoryController  extends BaseController<ShopCategory> {
-/**
-* 服务对象
-*/
+public class ShopCategoryController extends BaseController<ShopCategory> implements ShopCategoryRemoteController {
+    /**
+     * 服务对象
+     */
     @Autowired
     private ShopCategoryService shopCategoryService;
+    @Autowired
+    private UploadAdapter uploadAdapter;
+    @Autowired
+    private CountryAdapter countryAdapter;
 
     /**
-     *  获取商品类型
+     * 获取商品类型
+     *
      * @return {@link BaseResponse }<{@link AddMenuVo }>
      */
     @GetMapping("/getShopType")
@@ -42,7 +58,8 @@ public class ShopCategoryController  extends BaseController<ShopCategory> {
     }
 
     /**
-     *  获取二级热门商品类型
+     * 获取二级热门商品类型
+     *
      * @return {@link BaseResponse }<{@link AddMenuVo }>
      */
     @GetMapping("/getLevelToShopType")
@@ -50,4 +67,152 @@ public class ShopCategoryController  extends BaseController<ShopCategory> {
         return success(shopCategoryService.getLevelToShopType(param));
     }
 
+    /**
+     * icon上传
+     */
+    @PostMapping("/uploadIcon")
+    public RPCBaseResponse<String> uploadIcon(MultipartFile file) {
+        return shopCategoryService.uploadIcon(file);
+    }
+
+    /**
+     * 通过id获取商品类型
+     */
+    @Override
+    @GetMapping("/getFormId")
+    public RPCBaseResponse<ShopCategoryVo> getFormId(String id) {
+        RPCBaseResponse<ShopCategory> shopCurrencyRPCBaseResponse = super.getId(id);
+        RPCBaseResponse<ShopCategoryVo> shopCurrencyVoRPCBaseResponse = new RPCBaseResponse<>();
+        BeanUtils.copyProperties(shopCurrencyRPCBaseResponse, shopCurrencyVoRPCBaseResponse);
+        return shopCurrencyVoRPCBaseResponse;
+    }
+
+    /**
+     * 通过id更新商品类型
+     */
+    @Override
+    @PostMapping("/updateTargetFormId")
+    public RPCBaseResponse<ShopCategoryVo> updateTargetFormId(ShopCategoryDto entity) {
+        ShopCategory shopCurrency = new ShopCategory();
+        BeanUtils.copyProperties(entity, shopCurrency);
+        //调用接口获取地址,填入ImageUrl
+        // 检查 iconId 是否为空,
+        if (entity.getIconId() != null) {
+            shopCurrency.setImageUrl(uploadAdapter.getFormId(entity.getIconId()).toString());
+        }
+        RPCBaseResponse<ShopCategory> shopCurrencyRPCBaseResponse = super.updateTargetById(shopCurrency);
+        RPCBaseResponse<ShopCategoryVo> shopCurrencyVoRPCBaseResponse = new RPCBaseResponse<>();
+        BeanUtils.copyProperties(shopCurrencyRPCBaseResponse, shopCurrencyVoRPCBaseResponse);
+        return shopCurrencyVoRPCBaseResponse;
+    }
+
+    /**
+     * 新增商品类型
+     */
+    @Override
+    @PostMapping("/saveFormTarget")
+    public RPCBaseResponse<ShopCategoryVo> saveFormTarget(@RequestBody ShopCategoryDto entity) {
+        ShopCategory shopCurrency = new ShopCategory();
+        BeanUtils.copyProperties(entity, shopCurrency);
+        //调用接口获取地址,填入ImageUrl
+        // 检查 iconId 是否为空,避免 NullPointerException
+        if (entity.getIconId() != null) {
+            shopCurrency.setImageUrl(uploadAdapter.getFormId(entity.getIconId()).toString());
+        } else {
+            shopCurrency.setImageUrl(null);
+        }
+        RPCBaseResponse<ShopCategory> shopCurrencyRPCBaseResponse = super.saveTarget(shopCurrency);
+        RPCBaseResponse<ShopCategoryVo> shopCurrencyVoRPCBaseResponse = new RPCBaseResponse<>();
+        BeanUtils.copyProperties(shopCurrencyRPCBaseResponse, shopCurrencyVoRPCBaseResponse);
+        return shopCurrencyVoRPCBaseResponse;
+    }
+
+    /**
+     * 删除商品类型
+     */
+    @Override
+    @PostMapping("/deleteTargetFormId")
+    public RPCBaseResponse<ShopCategoryVo> deleteTargetFormId(List<String> ids) {
+        RPCBaseResponse<ShopCategory> shopCurrencyRPCBaseResponse = super.deleteTargetById(ids);
+        RPCBaseResponse<ShopCategoryVo> shopCurrencyVoRPCBaseResponse = new RPCBaseResponse<>();
+        BeanUtils.copyProperties(shopCurrencyRPCBaseResponse, shopCurrencyVoRPCBaseResponse);
+        return shopCurrencyVoRPCBaseResponse;
+    }
+
+    /**
+     * 获取所有商品类型(树形结构)
+     */
+    @Override
+    @GetMapping("/getAllForm")
+    public RPCBaseResponse<List<ShopCategoryVo>> getAllForm() {
+        RPCBaseResponse<List<ShopCategory>> shopCurrencyRPCBaseResponse = super.listAll();
+
+        // 创建一个用于存储每个节点的映射
+        Map<Long, ShopCategoryVo> categoryMap = new HashMap<>();
+        List<ShopCategoryVo> result = new ArrayList<>();
+        // 创建一个 Map,用于存储 countryId 对应的数据
+        Map<String, BaseCountryVo> countryDataMap = new HashMap<>();
+
+        // 将所有 ShopCategory 转换为 ShopCategoryVo,并存储在 map 中
+        if (shopCurrencyRPCBaseResponse.getData() != null) {
+            for (ShopCategory category : shopCurrencyRPCBaseResponse.getData()) {
+                ShopCategoryVo categoryVo = new ShopCategoryVo();
+                BeanUtils.copyProperties(category, categoryVo);
+                categoryMap.put(category.getId(), categoryVo);
+
+                // 利用 countryId 查找相关数据并存储到 countryDataMap 中
+                if (category.getCountryId() != null) {
+                    // 假设 countryAdapter.getFormId 是 RPCBaseResponse<BaseCountryServeVo> 类型
+                    RPCBaseResponse<BaseCountryServeVo> countryResponse = countryAdapter.getFormId(category.getCountryId());
+
+                    // 确保 countryResponse 不为 null,并提取数据
+                    if (countryResponse != null && countryResponse.getData() != null) {
+                        BaseCountryServeVo serveVo = countryResponse.getData();
+                        BaseCountryVo countryData = convertToBaseCountryVo(serveVo); // 需要实现此方法进行转换
+                        countryDataMap.put(category.getCountryId(), countryData);
+                    }
+                }
+            }
+
+            // 构建树结构
+            for (ShopCategoryVo categoryVo : categoryMap.values()) {
+                if (categoryVo.getParentId() == null || categoryVo.getParentId() == 0) {
+                    result.add(categoryVo);
+                } else {
+                    ShopCategoryVo parent = categoryMap.get(categoryVo.getParentId());
+                    if (parent != null) {
+                        if (parent.getChildren() == null) {
+                            parent.setChildren(new ArrayList<>());
+                        }
+                        parent.getChildren().add(categoryVo);
+                    }
+                }
+
+                // 如果有对应的 countryData,将其添加到 categoryVo 的 map 属性中
+                if (countryDataMap.containsKey(categoryVo.getCountryId())) {
+                    Map<String, Object> countryDataMapEntry = new HashMap<>();
+                    countryDataMapEntry.put("countryData", countryDataMap.get(categoryVo.getCountryId()));
+                    categoryVo.setMap(countryDataMapEntry);
+                }
+            }
+        }
+        // 创建返回的 RPCBaseResponse
+        RPCBaseResponse<List<ShopCategoryVo>> shopCurrencyVoRPCBaseResponse = new RPCBaseResponse<>();
+        BeanUtils.copyProperties(shopCurrencyRPCBaseResponse, shopCurrencyVoRPCBaseResponse);
+        shopCurrencyVoRPCBaseResponse.setData(result); // 设置树形结构的根节点
+
+        return shopCurrencyVoRPCBaseResponse;
+    }
+
+    // 实现 BaseCountryServeVo 到 BaseCountryVo 的转换方法
+    private BaseCountryVo convertToBaseCountryVo(BaseCountryServeVo serveVo) {
+        BaseCountryVo countryVo = new BaseCountryVo();
+        // 假设 serveVo 有与 countryVo 对应的字段
+        countryVo.setId(serveVo.getId());
+        countryVo.setCountryNameZh(serveVo.getCountryNameZh());
+        countryVo.setCountryNameEn(serveVo.getCountryNameEn());
+        countryVo.setAreaCode(serveVo.getAreaCode());
+        return countryVo;
+    }
+
 }

+ 8 - 4
edu-travel-service/edu-travel-service-commodity/src/main/java/edu/travel/commodity/web/ShopReviewController.java

@@ -59,19 +59,23 @@ public class ShopReviewController extends BaseController<ShopReview> implements
     public RPCBaseResponse<String> addReview(@RequestBody AddReviewDto params) {
         return success(shopReviewService.addReview(params));
     }
+
     /**
      * 上传评论图片
      */
     @PostMapping("/uploadReviewImage")
     public RPCBaseResponse<String> uploadReviewImage(MultipartFile file) {
-        return shopReviewService.uploadReviewImage(file);    }
-/**
- * 上传多张图片/视频
- */
+        return shopReviewService.uploadReviewImage(file);
+    }
+
+    /**
+     * 上传多张图片/视频
+     */
     @PostMapping("/uploadReviewImages")
     public RPCBaseResponse<String> uploadReviewImages(List<MultipartFile> files) {
         return shopReviewService.uploadReviewImages(files);
     }
+
     /**
      * 通过id查找商品评论
      */

+ 0 - 8
edu-travel-service/edu-travel-service-tenement/src/main/java/edu/travel/commodity/service/impl/ShopUnitService.java

@@ -1,8 +0,0 @@
-package edu.travel.commodity.service.impl;
-
-import edu.travel.entity.ShopUnit;
-import com.baomidou.mybatisplus.extension.service.IService;
-public interface ShopUnitService extends IService<ShopUnit>{
-
-
-}