lyx 1 месяц назад
Родитель
Сommit
eba8efec2b

+ 106 - 30
alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java

@@ -43,6 +43,7 @@ import shop.alien.util.common.DistanceUtil;
 import shop.alien.util.common.constant.CouponStatusEnum;
 import shop.alien.util.common.constant.CouponTypeEnum;
 import shop.alien.util.common.constant.OrderStatusEnum;
+
 import javax.annotation.Resource;
 import java.io.File;
 import java.io.IOException;
@@ -56,6 +57,7 @@ import java.time.format.DateTimeFormatterBuilder;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -1876,56 +1878,119 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
     @Override
     public int saveOrUpdateStoreInfo(StoreInfoDto storeInfodto) {
         if (storeInfodto.getId() != null) {
-            //验当前店铺存在未完成的订单及正在销售的商品
+            //验当前店铺存在未完成的订单及正在销售的商品
             verificationStoreInfoStatus(storeInfodto);
 
-            //获取经营板块id
+            // 1. 处理经营板块及经营种类
             Integer businessSection = storeInfodto.getBusinessSection();
-            //查询经营板块名称
-            StoreDictionary businessSectionName = storeDictionaryMapper.selectOne(new LambdaQueryWrapper<StoreDictionary>().eq(StoreDictionary::getDictId, businessSection).eq(StoreDictionary::getTypeName, "business_section"));
-            //查询经营种类
+            StoreDictionary businessSectionDict = null;
             List<String> businessTypeNames = new ArrayList<>();
+
+            // 查询经营板块(非空判断,避免后续空指针)
+            if (Objects.nonNull(businessSection)) {
+                businessSectionDict = storeDictionaryMapper.selectOne(
+                        new LambdaQueryWrapper<StoreDictionary>()
+                                .eq(StoreDictionary::getDictId, businessSection)
+                                .eq(StoreDictionary::getTypeName, "business_section")
+                );
+                // 若经营板块不存在,可根据业务抛出异常或默认处理
+                if (Objects.isNull(businessSectionDict)) {
+                    throw new IllegalArgumentException("经营板块不存在:" + businessSection);
+                }
+            }
+
+            // 批量查询经营种类(替代循环查询,解决N+1问题)
             List<String> businessTypes = storeInfodto.getBusinessTypes();
-            if (!CollectionUtils.isEmpty(businessTypes)) {
-                //获取经营种类名称
-                for (String businessType : businessTypes) {
-                    StoreDictionary storeDictionary = storeDictionaryMapper.selectOne(new LambdaQueryWrapper<StoreDictionary>().eq(StoreDictionary::getDictId, businessType).eq(StoreDictionary::getParentId, businessSectionName.getId()));
-                    businessTypeNames.add(storeDictionary.getDictDetail());
+            if (Objects.nonNull(businessSectionDict) && !CollectionUtils.isEmpty(businessTypes)) {
+                // 一次查询所有符合条件的经营种类
+                List<StoreDictionary> typeDicts = storeDictionaryMapper.selectList(
+                        new LambdaQueryWrapper<StoreDictionary>()
+                                .in(StoreDictionary::getDictId, businessTypes) // 批量匹配id
+                                .eq(StoreDictionary::getParentId, businessSectionDict.getId())
+                );
+                // 转为Map<dictId, StoreDictionary>,方便快速获取
+                Map<String, StoreDictionary> typeDictMap = typeDicts.stream()
+                        .collect(Collectors.toMap(
+                                dict -> dict.getDictId().toString(), // 假设dictId是字符串类型,若为数字需转换
+                                Function.identity(),
+                                (existing, replacement) -> existing // 处理重复id(理论上不会有)
+                        ));
+                // 提取经营种类名称
+                for (String typeId : businessTypes) {
+                    StoreDictionary dict = typeDictMap.get(typeId);
+                    if (Objects.nonNull(dict)) {
+                        businessTypeNames.add(dict.getDictDetail());
+                    } else {
+                        // 可选:记录无效的经营种类id,便于排查
+                        log.warn("无效的经营种类id:" + typeId + "(所属板块:" + businessSectionDict.getDictDetail() + ")");
+                    }
                 }
             }
+
+            // 2. 构建StoreInfo对象
             StoreInfo storeInfo = new StoreInfo();
             BeanUtils.copyProperties(storeInfodto, storeInfo);
 
-            //存入经纬度
-            if (StringUtils.isEmpty(storeInfodto.getStorePositionLongitude()) || StringUtils.isEmpty(storeInfodto.getStorePositionLatitude())) {
-                StoreInfo storeIn = storeInfoMapper.selectById(storeInfodto.getId());
-                storeInfo.setStorePosition(storeIn.getStorePosition());
+            // 3. 处理经纬度
+            String longitude = storeInfodto.getStorePositionLongitude();
+            String latitude = storeInfodto.getStorePositionLatitude();
+            if (StringUtils.isEmpty(longitude) || StringUtils.isEmpty(latitude)) {
+                // 经纬度为空时,复用原数据
+                StoreInfo oldStore = storeInfoMapper.selectById(storeInfodto.getId());
+                if (Objects.nonNull(oldStore)) {
+                    storeInfo.setStorePosition(oldStore.getStorePosition());
+                }
             } else {
-                storeInfo.setStorePosition(storeInfodto.getStorePositionLongitude() + "," + storeInfodto.getStorePositionLatitude());
+                // 拼接经纬度
+                storeInfo.setStorePosition(longitude + "," + latitude);
             }
 
-            //存入门店状态
+            // 4. 设置门店状态、经营板块及类型
             storeInfo.setStoreStatus(storeInfodto.getStoreStatus());
-            //板块及类型
-            storeInfo.setBusinessSection(businessSection);
-            storeInfo.setBusinessSectionName(businessSectionName.getDictDetail());
+            // 经营板块(非空时才设置)
+            if (Objects.nonNull(businessSection)) {
+                storeInfo.setBusinessSection(businessSection);
+            }
+            // 经营板块名称(非空时才设置)
+            if (Objects.nonNull(businessSectionDict)) {
+                storeInfo.setBusinessSectionName(businessSectionDict.getDictDetail());
+            }
+            // 经营种类及名称(非空时拼接)
             if (!CollectionUtils.isEmpty(businessTypes) && !CollectionUtils.isEmpty(businessTypeNames)) {
                 storeInfo.setBusinessTypes(String.join(",", businessTypes));
                 storeInfo.setBusinessTypesName(String.join(",", businessTypeNames));
             }
-            //处理一下行政区域信息
-            EssentialCityCode essentialCityCode1 = essentialCityCodeMapper.selectOne(new LambdaQueryWrapper<EssentialCityCode>().eq(EssentialCityCode::getAreaCode, storeInfo.getAdministrativeRegionProvinceAdcode()));
-            storeInfo.setAdministrativeRegionProvinceName(essentialCityCode1.getAreaName());
-            EssentialCityCode essentialCityCode2 = essentialCityCodeMapper.selectOne(new LambdaQueryWrapper<EssentialCityCode>().eq(EssentialCityCode::getAreaCode, storeInfo.getAdministrativeRegionCityAdcode()));
-            storeInfo.setAdministrativeRegionCityName(essentialCityCode2.getAreaName());
-            EssentialCityCode essentialCityCode3 = essentialCityCodeMapper.selectOne(new LambdaQueryWrapper<EssentialCityCode>().eq(EssentialCityCode::getAreaCode, storeInfo.getAdministrativeRegionDistrictAdcode()));
-            storeInfo.setAdministrativeRegionDistrictName(essentialCityCode3.getAreaName());
-            int num = storeInfoMapper.updateById(storeInfo);
-            if (!StringUtils.isEmpty(storeInfodto.getStorePositionLongitude()) && !StringUtils.isEmpty(storeInfodto.getStorePositionLatitude())) {
-                nearMeService.inGeolocation(new Point(Double.parseDouble(storeInfodto.getStorePositionLongitude()), Double.parseDouble(storeInfodto.getStorePositionLatitude())), storeInfo.getId().toString(), Boolean.TRUE);
+
+            // 5. 处理行政区域信息(抽取为方法,减少重复) 不存在单独查的情况
+            if (!Objects.isNull(storeInfo.getAdministrativeRegionProvinceAdcode())) {
+
+                storeInfo.setAdministrativeRegionProvinceName(
+                        getAreaName(storeInfo.getAdministrativeRegionProvinceAdcode())
+                );
+                storeInfo.setAdministrativeRegionCityName(
+                        getAreaName(storeInfo.getAdministrativeRegionCityAdcode())
+                );
+                storeInfo.setAdministrativeRegionDistrictName(
+                        getAreaName(storeInfo.getAdministrativeRegionDistrictAdcode())
+                );
             }
-            return num;
 
+            // 6. 执行更新
+            int updateNum = storeInfoMapper.updateById(storeInfo);
+
+            // 7. 更新地理位置信息(处理经纬度解析异常)
+            if (!StringUtils.isEmpty(longitude) && !StringUtils.isEmpty(latitude)) {
+                try {
+                    double lon = Double.parseDouble(longitude);
+                    double lat = Double.parseDouble(latitude);
+                    nearMeService.inGeolocation(new Point(lon, lat), storeInfo.getId().toString(), Boolean.TRUE);
+                } catch (NumberFormatException e) {
+                    log.error("经纬度解析失败:longitude=" + longitude + ", latitude=" + latitude);
+                    // 可选:根据业务是否抛出异常,或忽略
+                    // throw new IllegalArgumentException("经纬度格式错误", e);
+                }
+            }
+            return updateNum;
         } else {
             StoreInfo storeInfo = new StoreInfo();
             BeanUtils.copyProperties(storeInfodto, storeInfo);
@@ -1934,6 +1999,17 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
         }
     }
 
+    // 抽取:根据区域编码查询区域名称(通用方法)
+    private String getAreaName(String areaCode) {
+        if (StringUtils.isEmpty(areaCode)) {
+            return ""; // 或返回null,根据业务定义
+        }
+        EssentialCityCode cityCode = essentialCityCodeMapper.selectOne(
+                new LambdaQueryWrapper<EssentialCityCode>().eq(EssentialCityCode::getAreaCode, areaCode)
+        );
+        return Objects.nonNull(cityCode) ? cityCode.getAreaName() : "";
+    }
+
     @Override
     public Map<String, String> storeInfoVerification(int id) {
         Map<String, String> storeInfoMap = new HashMap<>();