|
@@ -2,44 +2,122 @@ package edu.travel.commodity.service.impl;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
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.core.util.ObjectUtil;
|
|
import cn.hutool.json.JSONArray;
|
|
import cn.hutool.json.JSONArray;
|
|
import cn.hutool.json.JSONUtil;
|
|
import cn.hutool.json.JSONUtil;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
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.BaseConstant;
|
|
import edu.travel.commodity.constant.RedisKey;
|
|
import edu.travel.commodity.constant.RedisKey;
|
|
import edu.travel.commodity.entity.ShopCategory;
|
|
import edu.travel.commodity.entity.ShopCategory;
|
|
import edu.travel.commodity.mapper.ShopCategoryMapper;
|
|
import edu.travel.commodity.mapper.ShopCategoryMapper;
|
|
import edu.travel.commodity.service.ShopCategoryService;
|
|
import edu.travel.commodity.service.ShopCategoryService;
|
|
|
|
+import edu.travel.commodity.utils.FIleUtil;
|
|
import edu.travel.commodity.utils.RedisUtil;
|
|
import edu.travel.commodity.utils.RedisUtil;
|
|
import edu.travel.remote.dto.BaseDto;
|
|
import edu.travel.remote.dto.BaseDto;
|
|
|
|
+import edu.travel.remote.dto.ShopCategoryDto;
|
|
import edu.travel.remote.dto.ShopTypeDto;
|
|
import edu.travel.remote.dto.ShopTypeDto;
|
|
|
|
+import edu.travel.remote.feign.mode.vo.banner.BannerVo;
|
|
|
|
+import edu.travel.remote.upload.dto.EduFileDTO;
|
|
|
|
+import edu.travel.remote.vo.ShopCategoryVo;
|
|
import edu.travel.remote.vo.ShopTypeVo;
|
|
import edu.travel.remote.vo.ShopTypeVo;
|
|
|
|
+import edu.travel.rpc.RPCBaseResponse;
|
|
|
|
+import edu.travel.vo.BaseCountryServeVo;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
+import org.springframework.web.servlet.View;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.List;
|
|
|
|
|
|
+import java.util.*;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
+import static edu.travel.rpc.RPCBaseResponse.error;
|
|
|
|
+import static edu.travel.rpc.RPCBaseResponse.success;
|
|
|
|
+
|
|
@Service
|
|
@Service
|
|
public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, ShopCategory> implements ShopCategoryService {
|
|
public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, ShopCategory> implements ShopCategoryService {
|
|
@Autowired
|
|
@Autowired
|
|
private RedisUtil redisUtil;
|
|
private RedisUtil redisUtil;
|
|
|
|
+ @Autowired
|
|
|
|
+ private UploadAdapter uploadAdapter;
|
|
|
|
+ @Autowired
|
|
|
|
+ private CountryAdapter countryAdapter;
|
|
|
|
+ @Autowired
|
|
|
|
+ private ShopCategoryMapper shopCategoryMapper;
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public RPCBaseResponse<Page<ShopCategoryVo>> getCategoryPage(ShopCategoryDto shopCategoryDto) {
|
|
|
|
+ // 查询商品类型数据,确保返回数据正确
|
|
|
|
+ List<ShopCategoryVo> categoryVos = shopCategoryMapper.selectCategoryWithCountry(shopCategoryDto);
|
|
|
|
+ int total = shopCategoryMapper.countAll(shopCategoryDto);
|
|
|
|
+
|
|
|
|
+ // 提取 CountryID
|
|
|
|
+ Set<String> countryIds = categoryVos.stream()
|
|
|
|
+ .map(ShopCategoryVo::getCountryId)
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
+
|
|
|
|
+ // 查询国家信息
|
|
|
|
+ Map<String, ShopCategoryVo> countryMap = fetchCountryData(countryIds);
|
|
|
|
+
|
|
|
|
+ // 遍历并设置国家信息
|
|
|
|
+ for (ShopCategoryVo shopCategoryVo : categoryVos) {
|
|
|
|
+ if (shopCategoryVo.getMap() == null) {
|
|
|
|
+ shopCategoryVo.setMap(new HashMap<>());
|
|
|
|
+ }
|
|
|
|
+ // 设置国家信息到 map 中
|
|
|
|
+ if (countryMap.containsKey(shopCategoryVo.getCountryId())) {
|
|
|
|
+ shopCategoryVo.getMap().put("countryServe", countryMap.get(shopCategoryVo.getCountryId()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 封装返回结果
|
|
|
|
+ Page<ShopCategoryVo> pageVoLink = new Page<>();
|
|
|
|
+ pageVoLink.setRecords(categoryVos);
|
|
|
|
+ pageVoLink.setTotal(total);
|
|
|
|
+ pageVoLink.setCurrent(shopCategoryDto.getCurrentPage());
|
|
|
|
+ pageVoLink.setSize(shopCategoryDto.getPageSize());
|
|
|
|
+ return new RPCBaseResponse<>(200, "SUCCESS", pageVoLink);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查询国家信息
|
|
|
|
+ private Map<String, ShopCategoryVo> fetchCountryData(Set<String> countryIds) {
|
|
|
|
+ Map<String, ShopCategoryVo> countryMap = new HashMap<>();
|
|
|
|
+ for (String countryId : countryIds) {
|
|
|
|
+ // 假设 countryAdapter.getFormId(countryId) 返回 RPCBaseResponse<BaseCountryServeVo>
|
|
|
|
+ BaseCountryServeVo countryServeVo = countryAdapter.getFormId(countryId).getData();
|
|
|
|
+ if (countryServeVo != null) {
|
|
|
|
+ ShopCategoryVo countryVo = new ShopCategoryVo(); // 使用 ShopCategoryVo 来存储国家信息
|
|
|
|
+ countryVo.setCountryId(countryId);
|
|
|
|
+ countryVo.setMap(new HashMap<>());
|
|
|
|
+ countryVo.getMap().put("countryNameZh", countryServeVo.getCountryNameZh());
|
|
|
|
+ countryVo.getMap().put("countryNameEn", countryServeVo.getCountryNameEn());
|
|
|
|
+ countryVo.getMap().put("countryNameLocal", countryServeVo.getCountryNameLocal());
|
|
|
|
+
|
|
|
|
+ // 将国家信息放入 countryMap
|
|
|
|
+ countryMap.put(countryId, countryVo);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return countryMap;
|
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public List<ShopTypeVo> getShopType(ShopTypeDto shopTypeDto) {
|
|
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);
|
|
JSONArray objects = JSONUtil.parseArray(string);
|
|
return JSONUtil.toList(objects, ShopTypeVo.class);
|
|
return JSONUtil.toList(objects, ShopTypeVo.class);
|
|
}
|
|
}
|
|
@@ -47,18 +125,18 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
|
|
//条件构建
|
|
//条件构建
|
|
query.eq(ShopCategory::getCountryId, shopTypeDto.getCountryId());
|
|
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);
|
|
query.orderByDesc(ShopCategory::getHeatValue);
|
|
- }else {
|
|
|
|
|
|
+ } else {
|
|
query.orderByDesc(ShopCategory::getSortOrder);
|
|
query.orderByDesc(ShopCategory::getSortOrder);
|
|
}
|
|
}
|
|
List<ShopCategory> list = list(query);
|
|
List<ShopCategory> list = list(query);
|
|
- if(list.isEmpty()){
|
|
|
|
|
|
+ if (list.isEmpty()) {
|
|
return new ArrayList<>();
|
|
return new ArrayList<>();
|
|
}
|
|
}
|
|
//父级
|
|
//父级
|
|
List<ShopCategory> collect = list.stream().filter(item -> item.getParentId().equals(0L)).collect(Collectors.toList());
|
|
List<ShopCategory> collect = list.stream().filter(item -> item.getParentId().equals(0L)).collect(Collectors.toList());
|
|
- if(collect.isEmpty()){
|
|
|
|
|
|
+ if (collect.isEmpty()) {
|
|
return new ArrayList<>();
|
|
return new ArrayList<>();
|
|
}
|
|
}
|
|
List<ShopTypeVo> parent = BeanUtil.copyToList(collect, ShopTypeVo.class);
|
|
List<ShopTypeVo> parent = BeanUtil.copyToList(collect, ShopTypeVo.class);
|
|
@@ -67,33 +145,74 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
|
|
List<ShopTypeVo> shopTypeVos = BeanUtil.copyToList(children, ShopTypeVo.class);
|
|
List<ShopTypeVo> shopTypeVos = BeanUtil.copyToList(children, ShopTypeVo.class);
|
|
shopCategory.setChildren(shopTypeVos);
|
|
shopCategory.setChildren(shopTypeVos);
|
|
}
|
|
}
|
|
- if(shopTypeDto.getIsHeat().equals(BaseConstant.BASIC_STATUS_NO_STR)){
|
|
|
|
|
|
+ if (shopTypeDto.getIsHeat().equals(BaseConstant.BASIC_STATUS_NO_STR)) {
|
|
//24小时热门过期
|
|
//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;
|
|
return parent;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public List<ShopTypeVo> getLevelToShopType(BaseDto param) {
|
|
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);
|
|
JSONArray objects = JSONUtil.parseArray(string);
|
|
return JSONUtil.toList(objects, ShopTypeVo.class);
|
|
return JSONUtil.toList(objects, ShopTypeVo.class);
|
|
}
|
|
}
|
|
LambdaQueryWrapper<ShopCategory> query = Wrappers.lambdaQuery();
|
|
LambdaQueryWrapper<ShopCategory> query = Wrappers.lambdaQuery();
|
|
//条件构建
|
|
//条件构建
|
|
query.eq(ShopCategory::getCountryId, param.getCountryId())
|
|
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);
|
|
List<ShopCategory> list = list(query);
|
|
- if(list.isEmpty()){
|
|
|
|
|
|
+ if (list.isEmpty()) {
|
|
return new ArrayList<>();
|
|
return new ArrayList<>();
|
|
}
|
|
}
|
|
List<ShopTypeVo> parent = BeanUtil.copyToList(list, ShopTypeVo.class);
|
|
List<ShopTypeVo> parent = BeanUtil.copyToList(list, ShopTypeVo.class);
|
|
//24小时热门过期
|
|
//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;
|
|
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();
|
|
|
|
+ }
|
|
}
|
|
}
|