Prechádzať zdrojové kódy

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	alien-store/src/main/java/shop/alien/store/controller/StoreStaffConfigController.java
#	alien-store/src/main/java/shop/alien/store/service/StoreStaffConfigService.java
#	alien-store/src/main/java/shop/alien/store/service/impl/StoreStaffConfigServiceImpl.java
penghao 2 týždňov pred
rodič
commit
310c872e75
18 zmenil súbory, kde vykonal 1710 pridanie a 98 odobranie
  1. 4 0
      alien-entity/src/main/java/shop/alien/entity/store/StoreDictionary.java
  2. 10 0
      alien-entity/src/main/java/shop/alien/entity/store/StoreStaffConfig.java
  3. 36 0
      alien-entity/src/main/java/shop/alien/entity/store/excelVo/BusinessSectionExcelVo.java
  4. 3 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/StoreInfoVo.java
  5. 26 0
      alien-entity/src/main/java/shop/alien/mapper/LifeUserViolationMapper.java
  6. 22 0
      alien-entity/src/main/java/shop/alien/mapper/StoreInfoMapper.java
  7. 15 11
      alien-job/src/main/java/shop/alien/job/store/AiTagJob.java
  8. 102 0
      alien-store/src/main/java/shop/alien/store/controller/PlatformBusinessSectionController.java
  9. 36 0
      alien-store/src/main/java/shop/alien/store/controller/StoreInfoController.java
  10. 49 0
      alien-store/src/main/java/shop/alien/store/controller/StoreStaffConfigController.java
  11. 76 73
      alien-store/src/main/java/shop/alien/store/service/LifeCommentService.java
  12. 58 0
      alien-store/src/main/java/shop/alien/store/service/PlatformBusinessSectionService.java
  13. 19 0
      alien-store/src/main/java/shop/alien/store/service/StoreInfoService.java
  14. 19 0
      alien-store/src/main/java/shop/alien/store/service/StoreStaffConfigService.java
  15. 967 0
      alien-store/src/main/java/shop/alien/store/service/impl/PlatformBusinessSectionServiceImpl.java
  16. 235 10
      alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java
  17. 29 0
      alien-store/src/main/java/shop/alien/store/service/impl/StoreStaffConfigServiceImpl.java
  18. 4 4
      alien-store/src/main/java/shop/alien/store/util/ai/AiAuthTokenUtil.java

+ 4 - 0
alien-entity/src/main/java/shop/alien/entity/store/StoreDictionary.java

@@ -80,6 +80,10 @@ public class StoreDictionary extends Model<StoreDictionary> {
     @TableField(exist = false)
     private List<StoreDictionary> storeDictionaryList;
 
+    @ApiModelProperty(value = "是否隐藏, 0:不隐藏, 1:隐藏")
+    @TableField("hidden")
+    private Integer hidden;
+
     @Override
     protected Serializable pkVal() {
         return this.id;

+ 10 - 0
alien-entity/src/main/java/shop/alien/entity/store/StoreStaffConfig.java

@@ -29,33 +29,43 @@ public class StoreStaffConfig extends Model<StoreStaffConfig> {
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
 
+    @ApiModelProperty(value = "员工职位")
     @TableField("staff_position")
     private String staffPosition;
 
+    @ApiModelProperty(value = "员工名称/昵称")
     @TableField("name")
     private String name;
 
+    @ApiModelProperty(value = "头像")
     @TableField("staff_image")
     private String staffImage;
 
+    @ApiModelProperty(value = "擅长项目")
     @TableField("proficient_projects")
     private String proficientProjects;
 
+    @ApiModelProperty(value = "标签")
     @TableField("tag")
     private String tag;
 
+    @ApiModelProperty(value = "个人简介")
     @TableField("personal_introduction")
     private String personalIntroduction;
 
+    @ApiModelProperty(value = "人员状态0-待审核 1-审核通过 2-审核拒绝")
     @TableField("status")
     private String status;
 
+    @ApiModelProperty(value = "店铺ID")
     @TableField("store_id")
     private Integer storeId;
 
+    @ApiModelProperty(value = "店铺名称")
     @TableField("store_name")
     private String storeName;
 
+    @ApiModelProperty(value = "拒绝原因")
     @TableField("rejection_reason")
     private String rejectionReason;
 

+ 36 - 0
alien-entity/src/main/java/shop/alien/entity/store/excelVo/BusinessSectionExcelVo.java

@@ -0,0 +1,36 @@
+package shop.alien.entity.store.excelVo;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import shop.alien.entity.store.excelVo.util.ExcelHeader;
+
+/**
+ * 经营版块Excel导入导出对象
+ *
+ * @author ssk
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@ApiModel(value = "BusinessSectionExcelVo对象", description = "经营版块Excel导入导出对象")
+public class BusinessSectionExcelVo {
+
+    @ExcelHeader("一级分类名称")
+    @ApiModelProperty(value = "一级分类名称(必填,如果二级和三级为空,则创建一级分类)")
+    private String firstLevelName;
+
+    @ExcelHeader("二级分类名称")
+    @ApiModelProperty(value = "二级分类名称(可选,如果三级为空,则创建二级分类)")
+    private String secondLevelName;
+
+    @ExcelHeader("三级分类名称")
+    @ApiModelProperty(value = "三级分类名称(可选,如果填写则创建三级分类)")
+    private String thirdLevelName;
+
+    @ExcelHeader("状态")
+    @ApiModelProperty(value = "状态为显示隐藏,如不填默认显示")
+    private String hidden;
+}
+

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreInfoVo.java

@@ -214,4 +214,7 @@ public class StoreInfoVo extends StoreInfo {
 
     @ApiModelProperty(value = "动态数量")
     private Integer dynamicsNum;
+
+    @ApiModelProperty(value = "推荐列表距离(米)")
+    private double distance3;
 }

+ 26 - 0
alien-entity/src/main/java/shop/alien/mapper/LifeUserViolationMapper.java

@@ -10,6 +10,7 @@ import shop.alien.entity.store.LifeUserViolation;
 import shop.alien.entity.store.vo.LifeUserViolationVo;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -104,4 +105,29 @@ public interface LifeUserViolationMapper extends BaseMapper<LifeUserViolation> {
     List<LifeUserViolationVo> getViolationList(
             @Param(Constants.WRAPPER) QueryWrapper<LifeUserViolationVo> queryWrapper
     );
+
+//    @Select("SELECT \n" +
+//            "    vio.id,\n" +
+//            "    dic.dict_detail as complaint_type,\n" +
+//            "    vio.reporting_user_id as reporter_user_id,\n" +
+//            "    vio.reporting_user_type as reporter_user_type,\n" +
+//            "    vio.reported_user_id,\n" +
+//            "    vio.reported_user_type,\n" +
+//            "    vio.goods_id as product_id,\n" +
+//            "    good.title as product_name,\n" +
+//            "    vio.other_reason_content as complaint_text,\n" +
+//            "    vio.report_evidence_img as evidence_images\n" +
+//            "FROM\n" +
+//            "\tlife_user_violation AS vio\n" +
+//            "\tLEFT JOIN\n" +
+//            "\tstore_dictionary AS dic\n" +
+//            "\tON \n" +
+//            "\t\tvio.dict_id = dic.dict_id AND\n" +
+//            "\t\tvio.dict_type = dic.type_name\n" +
+//            "\tLEFT JOIN\n" +
+//            "\tsecond_goods_record AS good\n" +
+//            "\tON \n" +
+//            "\t\tvio.goods_id = good.goods_id\n" +
+//            "WHERE vio.processing_status = 0 and vio.delete_flag = 0")
+//    List<Map<String, Object>> selectAiCheckList();
 }

+ 22 - 0
alien-entity/src/main/java/shop/alien/mapper/StoreInfoMapper.java

@@ -130,4 +130,26 @@ public interface StoreInfoMapper extends BaseMapper<StoreInfo> {
             "from store_info where id = #{storeId}"
             )
     Double getStoreDistance(@Param("position") String position,@Param("storeId") Integer storeId);
+
+    /**
+     * 更多推荐(用户端)
+     *
+     * @param queryWrapper 查询条件
+     * @return List<StoreInfoVo>
+     */
+    @Select("select a.*, img.img_url entranceImage,img1.img_url foodLicenceImageUrl,b.name store_contact, b.phone store_phone, b.id_card idCard, b.password, c.dict_detail store_status_str, d.dict_detail business_status_str, e.dict_detail store_type_str,  " +
+            "( " +
+            " select ifnull(round(avg(score), 1), 0) " +
+            " from store_evaluation eval " +
+            " where eval.store_id = a.id and eval.delete_flag = 0 " +
+            ") score " +
+            "from store_info a " +
+            "left join store_user b on a.id = b.store_id and a.delete_flag = 0 and b.delete_flag = 0 " +
+            "left join store_img img on img.store_id = a.id and img.img_type = 1 and img.delete_flag = 0 " +
+            "left join store_img img1 on img1.store_id = a.id and img1.img_type = 24 and img1.delete_flag = 0 " +
+            "left join store_dictionary c on a.store_status = c.dict_id and c.type_name = 'storeState' and c.delete_flag = 0 " +
+            "left join store_dictionary d on a.business_status = d.dict_id and d.type_name = 'businessStatus' and d.delete_flag = 0 " +
+            "left join store_dictionary e on e.type_name = 'storeType' and e.dict_id = a.store_type and e.delete_flag = 0 " +
+            "${ew.customSqlSegment}")
+    List<StoreInfoVo> getMoreRecommendedStores(@Param(Constants.WRAPPER) QueryWrapper<StoreInfoVo> queryWrapper);
 }

+ 15 - 11
alien-job/src/main/java/shop/alien/job/store/AiTagJob.java

@@ -646,8 +646,8 @@ public class AiTagJob {
                             Map<String, Object> jsonBody = new HashMap<>();
                             // text/img/video 三种维度一起传入 AI,便于一次完成合规审查
                             jsonBody.put("text", lifeUserDynamic.getContext());
-                            jsonBody.put("imgUrl", imageList);
-                            jsonBody.put("video", videoList);
+                            jsonBody.put("image_urls", imageList);
+                            jsonBody.put("video_urls", videoList);
 
                             HttpEntity<Map<String, Object>> request = new HttpEntity<>(jsonBody, aiHeaders);
                             ResponseEntity<String> response = null;
@@ -752,16 +752,20 @@ public class AiTagJob {
                                 if(code==200) {
                                     JSONObject dataNode = JSONObject.from(responseNode.get("data"));
                                     LifeUserDynamics dynamics = new LifeUserDynamics();
-                                    if (!(boolean) dataNode.get("is_compliant")) {
-                                        // 只要 AI 判定不合规,立即禁用动态并记录原因
-                                        dynamics.setId(lifeUserDynamic.getId());
-                                        dynamics.setEnableStatus(1);
-                                        dynamics.setReason(String.valueOf(dataNode.get("failure_reason")));
+                                    if ("completed".equals(dataNode.get("is_compliant"))) {
+                                        if (!(boolean) dataNode.get("is_compliant")) {
+                                            // 只要 AI 判定不合规,立即禁用动态并记录原因
+                                            dynamics.setId(lifeUserDynamic.getId());
+                                            dynamics.setEnableStatus(1);
+                                            dynamics.setReason(String.valueOf(dataNode.get("failure_reason")));
+                                        }
+                                        dynamics.setCheckFlag(2);
+                                        lifeUserDynamicsMapper.updateById(dynamics);
+                                        log.info("动态审核结果获取成功,AI返回内容: {}", response.getBody());
+                                        XxlJobHelper.handleSuccess("动态内容审核任务结果获取执行成功");
+                                    } else {
+                                        log.info("动态审核未完成,AI返回内容: {}", response.getBody());
                                     }
-                                    dynamics.setCheckFlag(2);
-                                    lifeUserDynamicsMapper.updateById(dynamics);
-                                    log.info("动态审核结果获取成功,AI返回内容: {}", response.getBody());
-                                    XxlJobHelper.handleSuccess("动态内容审核任务结果获取执行成功");
                                 } else {
                                     log.error("AI接口调用失败,错误码: " + code);
                                 }

+ 102 - 0
alien-store/src/main/java/shop/alien/store/controller/PlatformBusinessSectionController.java

@@ -0,0 +1,102 @@
+package shop.alien.store.controller;
+
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiOperationSupport;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreDictionary;
+import shop.alien.store.service.PlatformBusinessSectionService;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@Api(tags = {"2.5平台-经营版块管理"})
+@Slf4j
+@RestController
+@CrossOrigin
+@RequestMapping("/platformBusinessSection")
+@RequiredArgsConstructor
+public class PlatformBusinessSectionController {
+
+    private final PlatformBusinessSectionService platformBusinessSectionService;
+
+    @ApiOperation("查询经营种类(三级树形结构)")
+    @ApiOperationSupport(order = 1)
+    @GetMapping("/queryBusinessSectionTree")
+    public R<List<StoreDictionary>> queryBusinessSectionTree() {
+        log.info("platformBusinessSection.queryBusinessSectionTree");
+        List<StoreDictionary> result = platformBusinessSectionService.queryBusinessSectionTree();
+        return R.data(result);
+    }
+
+    @ApiOperation("新增经营种类(支持一级、二级、三级)")
+    @ApiOperationSupport(order = 2)
+    @PostMapping("/addBusinessSection")
+    public R<Boolean> addBusinessSection(@RequestBody StoreDictionary storeDictionary) {
+        log.info("platformBusinessSection.addBusinessSection:{}", storeDictionary);
+        try {
+            boolean result = platformBusinessSectionService.addBusinessSection(storeDictionary);
+            if (result) {
+                return R.success("新增成功");
+            } else {
+                return R.fail("新增失败");
+            }
+        } catch (IllegalArgumentException e) {
+            log.error("platformBusinessSection.addBusinessSection error: {}", e.getMessage());
+            return R.fail(e.getMessage());
+        } catch (Exception e) {
+            log.error("platformBusinessSection.addBusinessSection error", e);
+            return R.fail("新增失败:" + e.getMessage());
+        }
+    }
+
+    @ApiOperation("修改经营种类(支持一级、二级、三级)")
+    @ApiOperationSupport(order = 3)
+    @PutMapping("/updateBusinessSection")
+    public R<Boolean> updateBusinessSection(@RequestBody StoreDictionary storeDictionary) {
+        log.info("platformBusinessSection.updateBusinessSection:{}", storeDictionary);
+        try {
+            boolean result = platformBusinessSectionService.updateBusinessSection(storeDictionary);
+            if (result) {
+                return R.success("修改成功");
+            } else {
+                return R.fail("修改失败");
+            }
+        } catch (IllegalArgumentException e) {
+            log.error("platformBusinessSection.updateBusinessSection error: {}", e.getMessage());
+            return R.fail(e.getMessage());
+        } catch (Exception e) {
+            log.error("platformBusinessSection.updateBusinessSection error", e);
+            return R.fail("修改失败:" + e.getMessage());
+        }
+    }
+
+    @ApiOperation("批量导入经营版块")
+    @ApiOperationSupport(order = 4)
+    @PostMapping("/import")
+    public R<String> importBusinessSection(@RequestParam("file") MultipartFile file) {
+        log.info("platformBusinessSection.importBusinessSection fileName={}", 
+                file != null ? file.getOriginalFilename() : "null");
+        try {
+            return platformBusinessSectionService.importBusinessSection(file);
+        } catch (Exception e) {
+            log.error("platformBusinessSection.importBusinessSection error", e);
+            return R.fail("导入失败:" + e.getMessage());
+        }
+    }
+
+    @ApiOperation("下载经营版块导入模板")
+    @ApiOperationSupport(order = 5)
+    @GetMapping("/downloadTemplate")
+    public void downloadTemplate(HttpServletResponse response) throws IOException {
+        log.info("platformBusinessSection.downloadTemplate");
+        platformBusinessSectionService.downloadTemplate(response);
+    }
+
+}

+ 36 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreInfoController.java

@@ -754,4 +754,40 @@ public class StoreInfoController {
         return R.data(list);
     }
 
+    @ApiOperation(value = "AI服务-门头识别")
+    @ApiOperationSupport(order = 16)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "storeId", value = "门店id", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "imageUrl", value = "图片URL", dataType = "String", paramType = "query", required = true)
+    })
+    @GetMapping("/getStoreOcrData")
+    public R<Map<String, Object>> getStoreOcrData(@RequestParam("storeId") String storeId,
+                                             @RequestParam("imageUrl") String imageUrl) {
+        log.info("StoreInfoController.getStoreOcrData?storeId={},imageUrl={}", storeId, imageUrl);
+        if (storeId == null || storeId.trim().isEmpty() || imageUrl == null || imageUrl.trim().isEmpty()) {
+            return R.fail("门店ID与图片URL不能为空");
+        }
+        Map<String, Object> ocrData = null;
+        try {
+            ocrData = storeInfoService.getStoreOcrData(storeId, imageUrl);
+        } catch (Exception e) {
+            return R.fail("未查询到OCR识别数据");
+        }
+        return R.data(ocrData);
+    }
+
+
+    @ApiOperation(value = "更多推荐(用户端)")
+    @GetMapping("/getMoreRecommendedStores")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "lon", value = "经度", dataType = "double", paramType = "query", required = true),
+            @ApiImplicitParam(name = "lat", value = "纬度", dataType = "double", paramType = "query", required = true),
+            @ApiImplicitParam(name = "subcategory", value = "二级分类", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "threeLevelClassification", value = "三级分类", dataType = "int", paramType = "query")
+    })
+    public R<List<StoreInfoVo>> getMoreRecommendedStores(Double lon , Double lat, int subcategory, int threeLevelClassification) {
+        log.info("StoreInfoController.getMoreRecommendedStores?lon={},lat={},subcategory={},threeLevelClassification={}", lon,lat, subcategory, threeLevelClassification);
+        return R.data(storeInfoService.getMoreRecommendedStores(lon,lat, subcategory, threeLevelClassification));
+
+    }
 }

+ 49 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreStaffConfigController.java

@@ -98,4 +98,53 @@ public class StoreStaffConfigController {
         log.info("StoreStaffConfigController.setTopStatus?id={},topStatus={}", id, topStatus);
         return R.data(storeStaffConfigService.setTopStatus(id, topStatus));
     }
+
+    /**
+     * 员工列表查询接口(用户端)
+     *
+     * @param page    分页页数
+     * @param size    分页条数
+     * @param storeId 店铺ID
+     * @param status  员工状态
+     * @return 员工列表
+     */
+    @ApiOperation("员工列表查询(用户端)")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "分页页数", dataType = "Integer", paramType = "query", required = false),
+            @ApiImplicitParam(name = "size", value = "分页条数", dataType = "Integer", paramType = "query", required = false),
+            @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "status", value = "员工状态(0-待审核 1-审核通过 2-审核拒绝)", dataType = "String", paramType = "query", required = false)
+    })
+    @GetMapping("/queryStaffList")
+    public R<IPage<StoreStaffConfig>> queryStaffList(
+            @RequestParam(value = "page", defaultValue = "1") Integer page,
+            @RequestParam(value = "size", defaultValue = "10") Integer size,
+            @RequestParam(value = "storeId", required = true) Integer storeId,
+            @RequestParam(value = "status", required = false) String status) {
+        log.info("StoreStaffConfigController.queryStaffList?page={}&size={}&storeId={}&status={}", page, size, storeId, status);
+        IPage<StoreStaffConfig> result = storeStaffConfigService.queryStaffList(page, size, storeId, status);
+        return R.data(result);
+    }
+
+    /**
+     * 员工详情查询接口(用户端)
+     *
+     * @param id 员工主键id
+     * @return 员工详情
+     */
+    @ApiOperation("员工详情查询(用户端)")
+    @ApiOperationSupport(order = 6)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "员工主键id", dataType = "Integer", paramType = "query", required = true)
+    })
+    @GetMapping("/queryStaffDetail")
+    public R<StoreStaffConfig> queryStaffDetail(@RequestParam(value = "id", required = true) Integer id) {
+        log.info("StoreStaffConfigController.queryStaffDetail?id={}", id);
+        StoreStaffConfig result = storeStaffConfigService.queryStaffDetail(id);
+        if (result == null) {
+            return R.fail("员工不存在");
+        }
+        return R.data(result);
+    }
 }

+ 76 - 73
alien-store/src/main/java/shop/alien/store/service/LifeCommentService.java

@@ -62,39 +62,40 @@ public class LifeCommentService {
             lifeLikeRecord.setDianzanId(userId);
             lifeLikeRecord.setType(type);
             lifeLikeRecordMapper.insert(lifeLikeRecord);
-        }
-        if ("1".equals(type)) {
-            LambdaUpdateWrapper<StoreComment> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(StoreComment::getId, huifuId);
-            lambdaUpdateWrapper.setSql("like_count = like_count + 1");
-            return storeCommentMapper.update(null, lambdaUpdateWrapper);
-        } else if ("2".equals(type)) {
-            LambdaUpdateWrapper<LifeUserDynamics> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(LifeUserDynamics::getId, huifuId);
-            lambdaUpdateWrapper.setSql("dianzan_count = dianzan_count + 1");
-            int num = lifeUserDynamicsMapper.update(null, lambdaUpdateWrapper);
-            if (num > 0) insertNotice(userId, huifuId, type);
-            return num;
-        } else if ("3".equals(type)) {
-            LambdaUpdateWrapper<LifeActivity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(LifeActivity::getId, huifuId);
-            lambdaUpdateWrapper.setSql("dianzan_count = dianzan_count + 1");
-            return lifeActivityMapper.update(null, lambdaUpdateWrapper);
-        } else if ("4".equals(type)) {
-            LambdaUpdateWrapper<StoreMenu> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(StoreMenu::getId, huifuId);
-            lambdaUpdateWrapper.setSql("like_count = like_count + 1");
-            return storeRecommendMapper.update(null, lambdaUpdateWrapper);
-        } else if ("5".equals(type)) {
-            LambdaUpdateWrapper<StoreClockIn> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(StoreClockIn::getId, huifuId);
-            lambdaUpdateWrapper.setSql("like_count = like_count + 1");
-            return storeClockInMapper.update(null, lambdaUpdateWrapper);
-        } else if ("6".equals(type)) {
-            LambdaUpdateWrapper<SecondGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(SecondGoods::getId, huifuId);
-            lambdaUpdateWrapper.setSql("like_count = like_count + 1");
-            return secondGoodsMapper.update(null, lambdaUpdateWrapper);
+
+            if ("1".equals(type)) {
+                LambdaUpdateWrapper<StoreComment> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(StoreComment::getId, huifuId);
+                lambdaUpdateWrapper.setSql("like_count = like_count + 1");
+                return storeCommentMapper.update(null, lambdaUpdateWrapper);
+            } else if ("2".equals(type)) {
+                LambdaUpdateWrapper<LifeUserDynamics> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(LifeUserDynamics::getId, huifuId);
+                lambdaUpdateWrapper.setSql("dianzan_count = dianzan_count + 1");
+                int num = lifeUserDynamicsMapper.update(null, lambdaUpdateWrapper);
+                if (num > 0) insertNotice(userId, huifuId, type);
+                return num;
+            } else if ("3".equals(type)) {
+                LambdaUpdateWrapper<LifeActivity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(LifeActivity::getId, huifuId);
+                lambdaUpdateWrapper.setSql("dianzan_count = dianzan_count + 1");
+                return lifeActivityMapper.update(null, lambdaUpdateWrapper);
+            } else if ("4".equals(type)) {
+                LambdaUpdateWrapper<StoreMenu> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(StoreMenu::getId, huifuId);
+                lambdaUpdateWrapper.setSql("like_count = like_count + 1");
+                return storeRecommendMapper.update(null, lambdaUpdateWrapper);
+            } else if ("5".equals(type)) {
+                LambdaUpdateWrapper<StoreClockIn> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(StoreClockIn::getId, huifuId);
+                lambdaUpdateWrapper.setSql("like_count = like_count + 1");
+                return storeClockInMapper.update(null, lambdaUpdateWrapper);
+            } else if ("6".equals(type)) {
+                LambdaUpdateWrapper<SecondGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(SecondGoods::getId, huifuId);
+                lambdaUpdateWrapper.setSql("like_count = like_count + 1");
+                return secondGoodsMapper.update(null, lambdaUpdateWrapper);
+            }
         }
         return 0;
     }
@@ -117,47 +118,49 @@ public class LifeCommentService {
     }
 
     public int cancelLike(String userId, String huifuId, String type) {
-        LambdaUpdateWrapper<LifeLikeRecord> updateWrapper = new LambdaUpdateWrapper<>();
-        updateWrapper.eq(LifeLikeRecord::getDianzanId, userId);
-        updateWrapper.eq(LifeLikeRecord::getHuifuId, huifuId);
-        List<LifeLikeRecord> record = lifeLikeRecordMapper.selectList(updateWrapper);
+        LambdaQueryWrapper<LifeLikeRecord> lifeLikeRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lifeLikeRecordLambdaQueryWrapper.eq(LifeLikeRecord::getDianzanId, userId);
+        lifeLikeRecordLambdaQueryWrapper.eq(LifeLikeRecord::getHuifuId, huifuId);
+        lifeLikeRecordLambdaQueryWrapper.eq(LifeLikeRecord::getDianzanId, userId);
+        List<LifeLikeRecord> record = lifeLikeRecordMapper.selectList(lifeLikeRecordLambdaQueryWrapper);
         if (!CollectionUtils.isEmpty(record)) {
-            LambdaUpdateWrapper<LifeLikeRecord> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(LifeLikeRecord::getHuifuId, huifuId);
-            lambdaUpdateWrapper.eq(LifeLikeRecord::getDianzanId, userId);
-            lambdaUpdateWrapper.eq(LifeLikeRecord::getType, type);
-            lifeLikeRecordMapper.delete(lambdaUpdateWrapper);
-        }
-        if ("1".equals(type)) {
-            LambdaUpdateWrapper<StoreComment> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(StoreComment::getId, huifuId).gt(StoreComment::getLikeCount, 0);
-            lambdaUpdateWrapper.setSql("like_count = like_count - 1");
-            return storeCommentMapper.update(null, lambdaUpdateWrapper);
-        } else if ("2".equals(type)) {
-            LambdaUpdateWrapper<LifeUserDynamics> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(LifeUserDynamics::getId, huifuId).gt(LifeUserDynamics::getDianzanCount, 0);
-            lambdaUpdateWrapper.setSql("dianzan_count = dianzan_count - 1");
-            return lifeUserDynamicsMapper.update(null, lambdaUpdateWrapper);
-        } else if ("3".equals(type)) {
-            LambdaUpdateWrapper<LifeActivity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(LifeActivity::getId, huifuId).gt(LifeActivity::getDianzanCount, 0);
-            lambdaUpdateWrapper.setSql("dianzan_count = dianzan_count - 1");
-            return lifeActivityMapper.update(null, lambdaUpdateWrapper);
-        } else if ("4".equals(type)) {
-            LambdaUpdateWrapper<StoreMenu> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(StoreMenu::getId, huifuId).gt(StoreMenu::getLikeCount, 0);
-            lambdaUpdateWrapper.setSql("like_count = like_count - 1");
-            return storeRecommendMapper.update(null, lambdaUpdateWrapper);
-        } else if ("5".equals(type)) {
-            LambdaUpdateWrapper<StoreClockIn> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(StoreClockIn::getId, huifuId).gt(StoreClockIn::getLikeCount, 0);
-            lambdaUpdateWrapper.setSql("like_count = like_count - 1");
-            return storeClockInMapper.update(null, lambdaUpdateWrapper);
-        }else if ("6".equals(type)) {
-            LambdaUpdateWrapper<SecondGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            lambdaUpdateWrapper.eq(SecondGoods::getId, huifuId).gt(SecondGoods::getLikeCount, 0);
-            lambdaUpdateWrapper.setSql("like_count = like_count - 1");
-            return secondGoodsMapper.update(null, lambdaUpdateWrapper);
+            LambdaUpdateWrapper<LifeLikeRecord> lifeLikeRecordLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+            lifeLikeRecordLambdaUpdateWrapper.eq(LifeLikeRecord::getHuifuId, huifuId);
+            lifeLikeRecordLambdaUpdateWrapper.eq(LifeLikeRecord::getDianzanId, userId);
+            lifeLikeRecordLambdaUpdateWrapper.eq(LifeLikeRecord::getType, type);
+            lifeLikeRecordMapper.delete(lifeLikeRecordLambdaUpdateWrapper);
+
+            if ("1".equals(type)) {
+                LambdaUpdateWrapper<StoreComment> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(StoreComment::getId, huifuId).gt(StoreComment::getLikeCount, 0);
+                lambdaUpdateWrapper.setSql("like_count = like_count - 1");
+                return storeCommentMapper.update(null, lambdaUpdateWrapper);
+            } else if ("2".equals(type)) {
+                LambdaUpdateWrapper<LifeUserDynamics> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(LifeUserDynamics::getId, huifuId).gt(LifeUserDynamics::getDianzanCount, 0);
+                lambdaUpdateWrapper.setSql("dianzan_count = dianzan_count - 1");
+                return lifeUserDynamicsMapper.update(null, lambdaUpdateWrapper);
+            } else if ("3".equals(type)) {
+                LambdaUpdateWrapper<LifeActivity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(LifeActivity::getId, huifuId).gt(LifeActivity::getDianzanCount, 0);
+                lambdaUpdateWrapper.setSql("dianzan_count = dianzan_count - 1");
+                return lifeActivityMapper.update(null, lambdaUpdateWrapper);
+            } else if ("4".equals(type)) {
+                LambdaUpdateWrapper<StoreMenu> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(StoreMenu::getId, huifuId).gt(StoreMenu::getLikeCount, 0);
+                lambdaUpdateWrapper.setSql("like_count = like_count - 1");
+                return storeRecommendMapper.update(null, lambdaUpdateWrapper);
+            } else if ("5".equals(type)) {
+                LambdaUpdateWrapper<StoreClockIn> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(StoreClockIn::getId, huifuId).gt(StoreClockIn::getLikeCount, 0);
+                lambdaUpdateWrapper.setSql("like_count = like_count - 1");
+                return storeClockInMapper.update(null, lambdaUpdateWrapper);
+            }else if ("6".equals(type)) {
+                LambdaUpdateWrapper<SecondGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+                lambdaUpdateWrapper.eq(SecondGoods::getId, huifuId).gt(SecondGoods::getLikeCount, 0);
+                lambdaUpdateWrapper.setSql("like_count = like_count - 1");
+                return secondGoodsMapper.update(null, lambdaUpdateWrapper);
+            }
         }
         return 0;
     }

+ 58 - 0
alien-store/src/main/java/shop/alien/store/service/PlatformBusinessSectionService.java

@@ -0,0 +1,58 @@
+package shop.alien.store.service;
+
+import shop.alien.entity.store.StoreDictionary;
+import shop.alien.entity.result.R;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 平台经营版块管理Service
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2025/01/01
+ */
+public interface PlatformBusinessSectionService {
+
+    /**
+     * 查询经营种类(三级树形结构)
+     *
+     * @return 经营种类树形结构列表
+     */
+    List<StoreDictionary> queryBusinessSectionTree();
+
+    /**
+     * 新增经营种类(支持一级、二级、三级)
+     *
+     * @param storeDictionary 经营种类信息
+     * @return 新增结果
+     */
+    boolean addBusinessSection(StoreDictionary storeDictionary);
+
+    /**
+     * 修改经营种类(支持一级、二级、三级)
+     *
+     * @param storeDictionary 经营种类信息
+     * @return 修改结果
+     */
+    boolean updateBusinessSection(StoreDictionary storeDictionary);
+
+    /**
+     * 批量导入经营版块
+     *
+     * @param file Excel文件
+     * @return 导入结果
+     */
+    R<String> importBusinessSection(org.springframework.web.multipart.MultipartFile file);
+
+    /**
+     * 下载经营版块导入模板
+     *
+     * @param response HTTP响应
+     * @throws IOException IO异常
+     */
+    void downloadTemplate(HttpServletResponse response) throws IOException;
+}
+

+ 19 - 0
alien-store/src/main/java/shop/alien/store/service/StoreInfoService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.multipart.MultipartRequest;
+import shop.alien.entity.store.OcrImageUpload;
 import shop.alien.entity.store.StoreBusinessInfo;
 import shop.alien.entity.store.StoreImg;
 import shop.alien.entity.store.StoreInfo;
@@ -279,4 +280,22 @@ public interface StoreInfoService extends IService<StoreInfo> {
      *
      */
     int foodLicenceType(int id);
+
+    /**
+     * web-分页查询店铺信息
+     *
+
+     * @return IPage<StoreInfoVo>
+     */
+    List<StoreInfoVo> getMoreRecommendedStores(Double lon , Double lat, int subcategory, int threeLevelClassification);
+
+
+    /**
+     * 根据门店及图片地址查询最新OCR识别数据
+     *
+     * @param storeId  门店ID
+     * @param imageUrl 图片URL
+     * @return OCR识别记录
+     */
+    Map<String, Object> getStoreOcrData(String storeId, String imageUrl);
 }

+ 19 - 0
alien-store/src/main/java/shop/alien/store/service/StoreStaffConfigService.java

@@ -35,4 +35,23 @@ public interface StoreStaffConfigService {
      */
     Integer setTopStatus(Integer id, Integer topStatus);
 
+    /**
+     * 员工列表查询
+     *
+     * @param page    分页页数
+     * @param size    分页条数
+     * @param storeId 店铺ID
+     * @param status  员工状态
+     * @return 员工列表
+     */
+    IPage<StoreStaffConfig> queryStaffList(Integer page, Integer size, Integer storeId, String status);
+
+    /**
+     * 员工详情查询
+     *
+     * @param id 员工主键id
+     * @return 员工详情
+     */
+    StoreStaffConfig queryStaffDetail(Integer id);
+
 }

+ 967 - 0
alien-store/src/main/java/shop/alien/store/service/impl/PlatformBusinessSectionServiceImpl.java

@@ -0,0 +1,967 @@
+package shop.alien.store.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.StoreDictionary;
+import shop.alien.entity.store.excelVo.BusinessSectionExcelVo;
+import shop.alien.entity.store.excelVo.util.ExcelHeader;
+import shop.alien.mapper.StoreDictionaryMapper;
+import shop.alien.store.service.PlatformBusinessSectionService;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 平台经营版块管理ServiceImpl
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2025/01/01
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class PlatformBusinessSectionServiceImpl extends ServiceImpl<StoreDictionaryMapper, StoreDictionary> implements PlatformBusinessSectionService {
+
+    private final StoreDictionaryMapper storeDictionaryMapper;
+
+    /**
+     * 查询经营种类(三级树形结构)
+     *
+     * @return 经营种类树形结构列表
+     */
+    @Override
+    public List<StoreDictionary> queryBusinessSectionTree() {
+        // 查询所有经营种类数据
+        LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+        queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+        queryWrapper.orderByAsc(StoreDictionary::getDictId);
+        List<StoreDictionary> storeDictionaryList = storeDictionaryMapper.selectList(queryWrapper);
+
+        // 构建三级树形结构
+        return buildTreeOptimized(storeDictionaryList);
+    }
+
+    /**
+     * 构建树形结构(优化版)
+     *
+     * @param flatList 扁平列表
+     * @return 树形结构列表
+     */
+    private List<StoreDictionary> buildTreeOptimized(List<StoreDictionary> flatList) {
+        if (flatList == null || flatList.isEmpty()) {
+            return new ArrayList<>();
+        }
+
+        // 创建三个存储结构
+        Map<Integer, StoreDictionary> nodeMap = new HashMap<>();  // ID到节点的映射
+        Map<Integer, List<StoreDictionary>> parentChildMap = new HashMap<>();  // 父ID到子节点列表的映射
+        List<StoreDictionary> result = new ArrayList<>();  // 结果列表
+
+        // 填充nodeMap和parentChildMap
+        for (StoreDictionary entity : flatList) {
+            Integer id = entity.getId();
+            Integer parentId = entity.getParentId();
+
+            // 存入节点映射
+            nodeMap.put(id, entity);
+
+            // 初始化子节点列表
+            entity.setStoreDictionaryList(new ArrayList<>());
+
+            // 如果是根节点(parentId为null或0),直接添加到结果
+            if (parentId == null || parentId == 0) {
+                result.add(entity);
+            } else {
+                // 否则,记录父子关系
+                parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(entity);
+            }
+        }
+
+        // 建立父子关系
+        for (StoreDictionary entity : flatList) {
+            Integer id = entity.getId();
+            if (parentChildMap.containsKey(id)) {
+                entity.getStoreDictionaryList().addAll(parentChildMap.get(id));
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 新增经营种类(支持一级、二级、三级)
+     *
+     * @param storeDictionary 经营种类信息
+     * @return 新增结果
+     */
+    @Override
+    public boolean addBusinessSection(StoreDictionary storeDictionary) {
+        // 参数校验
+        if (storeDictionary == null || StringUtils.isBlank(storeDictionary.getDictDetail())) {
+            throw new IllegalArgumentException("经营种类描述不能为空");
+        }
+
+        // 设置固定字段
+        storeDictionary.setTypeName("business_section");
+//        storeDictionary.setTypeDetail("经营板块");
+        storeDictionary.setDeleteFlag(0);
+        storeDictionary.setCreatedTime(new Date());
+
+        // 处理 parent_id:如果为 null,设置为 0(一级)
+        Integer parentId = storeDictionary.getParentId();
+        if (parentId == null) {
+            parentId = 0;
+//            storeDictionary.setParentId(0);
+        }
+
+        // 如果是二级或三级,验证父节点是否存在
+        if (parentId != 0) {
+            StoreDictionary parent = storeDictionaryMapper.selectById(parentId);
+            if (parent == null || !"business_section".equals(parent.getTypeName()) || parent.getDeleteFlag() == 1) {
+                throw new IllegalArgumentException("父节点不存在或已删除");
+            }
+        }
+
+        // 生成 dict_id:查询同级(相同 parent_id)的最大 dict_id,然后 +1
+        String maxDictId = getMaxDictIdByParentId(parentId);
+        int nextDictId = (maxDictId == null ? 0 : Integer.parseInt(maxDictId)) + 1;
+        storeDictionary.setDictId(String.valueOf(nextDictId));
+
+        // 保存
+        return this.save(storeDictionary);
+    }
+
+    /**
+     * 修改经营种类(支持一级、二级、三级)
+     *
+     * @param storeDictionary 经营种类信息
+     * @return 修改结果
+     */
+    @Override
+    public boolean updateBusinessSection(StoreDictionary storeDictionary) {
+        // 参数校验
+        if (storeDictionary == null || storeDictionary.getId() == null) {
+            throw new IllegalArgumentException("ID不能为空");
+        }
+        if (StringUtils.isBlank(storeDictionary.getDictDetail())) {
+            throw new IllegalArgumentException("经营种类描述不能为空");
+        }
+
+        // 查询原记录
+        StoreDictionary existing = storeDictionaryMapper.selectById(storeDictionary.getId());
+        if (existing == null) {
+            throw new IllegalArgumentException("记录不存在");
+        }
+        if (!"business_section".equals(existing.getTypeName())) {
+            throw new IllegalArgumentException("该记录不是经营种类类型");
+        }
+        if (existing.getDeleteFlag() == 1) {
+            throw new IllegalArgumentException("该记录已删除");
+        }
+
+        // 判断是否是一级或二级节点
+        Integer existingParentId = existing.getParentId();
+        boolean isFirstLevel = (existingParentId == null || existingParentId == 0);
+        boolean isSecondLevel = false;
+        
+        // 如果不是一级节点,判断是否是二级节点(父节点是一级节点)
+        if (!isFirstLevel) {
+            StoreDictionary parent = storeDictionaryMapper.selectById(existingParentId);
+            if (parent != null) {
+                Integer grandParentId = parent.getParentId();
+                isSecondLevel = (grandParentId == null || grandParentId == 0);
+            }
+        }
+
+        // 处理 parent_id:如果为 null,设置为 0(一级)
+        Integer parentId = storeDictionary.getParentId();
+        if (parentId == null) {
+            parentId = 0;
+        }
+
+        // 标准化parentId用于比较(null转为0)
+        Integer normalizedParentId = (parentId == null) ? 0 : parentId;
+        Integer normalizedExistingParentId = (existingParentId == null) ? 0 : existingParentId;
+        String oldDictId = existing.getDictId();
+        String newDictId = storeDictionary.getDictId();
+        boolean parentIdChanged = !normalizedParentId.equals(normalizedExistingParentId);
+        
+        // 判断是否修改了关键字段(parent_id)
+        boolean keyFieldChanged = parentIdChanged;
+        
+        // 如果是一级或二级节点,且修改了关键字段(parent_id),检查是否有未删除的子节点
+        if ((isFirstLevel || isSecondLevel) && keyFieldChanged) {
+            boolean hasChildren = hasUndeletedChildren(existing.getId());
+            if (hasChildren) {
+                throw new IllegalArgumentException("该节点存在未删除的子节点,不允许修改关键字段(父节点)");
+            }
+        }
+        
+        // 如果修改了 parentId,需要验证新的父节点是否存在
+        if (parentIdChanged) {
+            if (parentId != 0) {
+                StoreDictionary parent = storeDictionaryMapper.selectById(parentId);
+                if (parent == null || !"business_section".equals(parent.getTypeName()) || parent.getDeleteFlag() == 1) {
+                    throw new IllegalArgumentException("父节点不存在或已删除");
+                }
+            }
+            
+            // 如果用户指定了新位置(newDictId不为空),使用用户指定的位置
+            // 否则,使用新节点下的最大+1
+            if (StringUtils.isBlank(newDictId)) {
+                String maxDictId = getMaxDictIdByParentId(parentId);
+                int nextDictId = (maxDictId == null ? 0 : Integer.parseInt(maxDictId)) + 1;
+                newDictId = String.valueOf(nextDictId);
+                storeDictionary.setDictId(newDictId);
+            }
+            
+            // 原节点下,原位置之后的记录需要前移(dictId - 1)
+            adjustSortOrderForMoveOut(existing.getId(), normalizedExistingParentId, oldDictId);
+            
+            // 新节点下,如果指定了新位置,需要调整新节点下的排序
+            if (StringUtils.isNotBlank(newDictId)) {
+                try {
+                    int newOrder = Integer.parseInt(newDictId);
+                    String maxDictId = getMaxDictIdByParentId(parentId);
+                    int maxOrder = (maxDictId == null ? 0 : Integer.parseInt(maxDictId));
+                    // 如果新位置不是最大+1,需要调整新节点下的排序
+                    if (newOrder <= maxOrder) {
+                        adjustSortOrderForMoveIn(existing.getId(), normalizedParentId, newDictId);
+                    }
+                } catch (NumberFormatException e) {
+                    log.warn("无法解析新dictId: {}", newDictId, e);
+                }
+            }
+        }
+
+        // 设置固定字段
+        storeDictionary.setTypeName("business_section");
+        // 如果没有指定删除标记,保持原有值;如果指定了,使用新值
+        Integer oldHidden = existing.getHidden();
+        Integer newHidden = storeDictionary.getHidden() == null ? oldHidden : storeDictionary.getHidden();
+        storeDictionary.setHidden(newHidden);
+        storeDictionary.setDeleteFlag(existing.getDeleteFlag()); // 保持原有删除标记
+        storeDictionary.setCreatedTime(existing.getCreatedTime()); // 保持原有创建时间
+        storeDictionary.setCreatedUserId(existing.getCreatedUserId()); // 保持原有创建人
+        storeDictionary.setUpdatedTime(new Date()); // 更新修改时间
+
+        // 处理排序逻辑:如果 parentId 没有改变,但 dictId 改变了,需要调整同级其他记录的排序
+        if (!parentIdChanged) {
+            // 如果 dictId 为空,保持原有值
+            if (StringUtils.isBlank(newDictId)) {
+                storeDictionary.setDictId(oldDictId);
+            } else if (!newDictId.equals(oldDictId)) {
+                // 调整同级其他记录的排序
+                adjustSortOrder(existing.getId(), normalizedParentId, oldDictId, newDictId);
+            }
+        }
+
+        // 更新当前节点
+        boolean updateResult = this.updateById(storeDictionary);
+        
+        // 如果是一级或二级节点,且hidden值发生了变化,同步更新所有子节点的hidden值
+        boolean hiddenChanged = (oldHidden == null && newHidden != null) || 
+                                (oldHidden != null && !oldHidden.equals(newHidden));
+        if (updateResult && (isFirstLevel || isSecondLevel) && hiddenChanged && newHidden != null) {
+            updateChildrenHidden(existing.getId(), newHidden);
+        }
+        
+        return updateResult;
+    }
+
+    /**
+     * 判断节点是否有未删除的子节点
+     *
+     * @param parentId 父节点ID
+     * @return 如果有未删除的子节点返回 true,否则返回 false
+     */
+    private boolean hasUndeletedChildren(Integer parentId) {
+        LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+        queryWrapper.eq(StoreDictionary::getParentId, parentId);
+        queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+        queryWrapper.last("LIMIT 1");
+        
+        StoreDictionary child = storeDictionaryMapper.selectOne(queryWrapper);
+        return child != null;
+    }
+
+    /**
+     * 递归更新子节点的显示/隐藏状态
+     * 当一级或二级节点的hidden值改变时,同步更新其所有子节点的hidden值
+     *
+     * @param parentId 父节点ID
+     * @param hidden 新的hidden值(0:不隐藏, 1:隐藏)
+     */
+    private void updateChildrenHidden(Integer parentId, Integer hidden) {
+        if (parentId == null || hidden == null) {
+            return;
+        }
+        
+        // 查询所有未删除的子节点
+        LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+        queryWrapper.eq(StoreDictionary::getParentId, parentId);
+        queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+        
+        List<StoreDictionary> children = storeDictionaryMapper.selectList(queryWrapper);
+        
+        if (children == null || children.isEmpty()) {
+            return;
+        }
+        
+        // 批量更新子节点的hidden值
+        Date updateTime = new Date();
+        for (StoreDictionary child : children) {
+            child.setHidden(hidden);
+            child.setUpdatedTime(updateTime);
+            storeDictionaryMapper.updateById(child);
+            
+            // 递归更新子节点的子节点(二级节点的子节点是三级节点)
+            updateChildrenHidden(child.getId(), hidden);
+        }
+    }
+
+    /**
+     * 根据 parent_id 获取同级最大 dict_id
+     *
+     * @param parentId 父节点ID
+     * @return 最大 dict_id,如果不存在则返回 null
+     */
+    private String getMaxDictIdByParentId(Integer parentId) {
+        LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+        queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+        
+        if (parentId == null || parentId == 0) {
+            queryWrapper.and(wrapper -> wrapper.isNull(StoreDictionary::getParentId)
+                    .or().eq(StoreDictionary::getParentId, 0));
+        } else {
+            queryWrapper.eq(StoreDictionary::getParentId, parentId);
+        }
+        
+        queryWrapper.orderByDesc(StoreDictionary::getDictId);
+        queryWrapper.last("LIMIT 1");
+        
+        StoreDictionary maxDict = storeDictionaryMapper.selectOne(queryWrapper);
+        return maxDict != null ? maxDict.getDictId() : null;
+    }
+
+    /**
+     * 调整排序:当记录的dictId改变时,调整同级其他记录的排序
+     * 上升则顺推:如果新dictId < 原dictId,将原dictId到新dictId之间的记录的dictId都+1
+     * 下降则顺升:如果新dictId > 原dictId,将原dictId到新dictId之间的记录的dictId都-1
+     *
+     * @param currentId 当前记录ID
+     * @param parentId 父节点ID
+     * @param oldDictId 原dictId
+     * @param newDictId 新dictId
+     */
+    private void adjustSortOrder(Integer currentId, Integer parentId, String oldDictId, String newDictId) {
+        try {
+            int oldOrder = Integer.parseInt(oldDictId);
+            int newOrder = Integer.parseInt(newDictId);
+            
+            // 如果排序没有改变,直接返回
+            if (oldOrder == newOrder) {
+                return;
+            }
+            
+            // 查询同级所有记录(排除当前记录)
+            LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+            queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+            queryWrapper.ne(StoreDictionary::getId, currentId);
+            
+            if (parentId == null || parentId == 0) {
+                queryWrapper.and(wrapper -> wrapper.isNull(StoreDictionary::getParentId)
+                        .or().eq(StoreDictionary::getParentId, 0));
+            } else {
+                queryWrapper.eq(StoreDictionary::getParentId, parentId);
+            }
+            
+            List<StoreDictionary> siblings = storeDictionaryMapper.selectList(queryWrapper);
+            
+            if (siblings == null || siblings.isEmpty()) {
+                return;
+            }
+            
+            // 上升则顺推:新dictId < 原dictId
+            if (newOrder < oldOrder) {
+                // 将新dictId到原dictId之间的记录的dictId都+1
+                for (StoreDictionary sibling : siblings) {
+                    try {
+                        int siblingOrder = Integer.parseInt(sibling.getDictId());
+                        if (siblingOrder >= newOrder && siblingOrder < oldOrder) {
+                            sibling.setDictId(String.valueOf(siblingOrder + 1));
+                            sibling.setUpdatedTime(new Date());
+                            storeDictionaryMapper.updateById(sibling);
+                        }
+                    } catch (NumberFormatException e) {
+                        log.warn("无法解析dictId: {}", sibling.getDictId(), e);
+                    }
+                }
+            } 
+            // 下降则顺升:新dictId > 原dictId
+            else if (newOrder > oldOrder) {
+                // 将原dictId到新dictId之间的记录的dictId都-1
+                for (StoreDictionary sibling : siblings) {
+                    try {
+                        int siblingOrder = Integer.parseInt(sibling.getDictId());
+                        if (siblingOrder > oldOrder && siblingOrder <= newOrder) {
+                            sibling.setDictId(String.valueOf(siblingOrder - 1));
+                            sibling.setUpdatedTime(new Date());
+                            storeDictionaryMapper.updateById(sibling);
+                        }
+                    } catch (NumberFormatException e) {
+                        log.warn("无法解析dictId: {}", sibling.getDictId(), e);
+                    }
+                }
+            }
+        } catch (NumberFormatException e) {
+            log.error("调整排序失败,dictId格式错误: oldDictId={}, newDictId={}", oldDictId, newDictId, e);
+        } catch (Exception e) {
+            log.error("调整排序失败", e);
+        }
+    }
+
+    /**
+     * 处理从原节点移出时的排序调整:原位置之后的记录需要前移(dictId - 1)
+     *
+     * @param currentId 当前记录ID
+     * @param oldParentId 原父节点ID
+     * @param oldDictId 原dictId
+     */
+    private void adjustSortOrderForMoveOut(Integer currentId, Integer oldParentId, String oldDictId) {
+        try {
+            int oldOrder = Integer.parseInt(oldDictId);
+            
+            // 查询原节点同级所有记录(排除当前记录)
+            LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+            queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+            queryWrapper.ne(StoreDictionary::getId, currentId);
+            
+            if (oldParentId == null || oldParentId == 0) {
+                queryWrapper.and(wrapper -> wrapper.isNull(StoreDictionary::getParentId)
+                        .or().eq(StoreDictionary::getParentId, 0));
+            } else {
+                queryWrapper.eq(StoreDictionary::getParentId, oldParentId);
+            }
+            
+            List<StoreDictionary> siblings = storeDictionaryMapper.selectList(queryWrapper);
+            
+            if (siblings == null || siblings.isEmpty()) {
+                return;
+            }
+            
+            // 原位置之后的记录需要前移(dictId - 1)
+            for (StoreDictionary sibling : siblings) {
+                try {
+                    int siblingOrder = Integer.parseInt(sibling.getDictId());
+                    if (siblingOrder > oldOrder) {
+                        sibling.setDictId(String.valueOf(siblingOrder - 1));
+                        sibling.setUpdatedTime(new Date());
+                        storeDictionaryMapper.updateById(sibling);
+                    }
+                } catch (NumberFormatException e) {
+                    log.warn("无法解析dictId: {}", sibling.getDictId(), e);
+                }
+            }
+        } catch (NumberFormatException e) {
+            log.error("移出节点排序调整失败,dictId格式错误: oldDictId={}", oldDictId, e);
+        } catch (Exception e) {
+            log.error("移出节点排序调整失败", e);
+        }
+    }
+
+    /**
+     * 处理移入新节点时的排序调整:新位置之后的记录需要后移(dictId + 1)
+     *
+     * @param currentId 当前记录ID
+     * @param newParentId 新父节点ID
+     * @param newDictId 新dictId
+     */
+    private void adjustSortOrderForMoveIn(Integer currentId, Integer newParentId, String newDictId) {
+        try {
+            int newOrder = Integer.parseInt(newDictId);
+            
+            // 查询新节点同级所有记录(排除当前记录)
+            LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+            queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+            queryWrapper.ne(StoreDictionary::getId, currentId);
+            
+            if (newParentId == null || newParentId == 0) {
+                queryWrapper.and(wrapper -> wrapper.isNull(StoreDictionary::getParentId)
+                        .or().eq(StoreDictionary::getParentId, 0));
+            } else {
+                queryWrapper.eq(StoreDictionary::getParentId, newParentId);
+            }
+            
+            List<StoreDictionary> siblings = storeDictionaryMapper.selectList(queryWrapper);
+            
+            if (siblings == null || siblings.isEmpty()) {
+                return;
+            }
+            
+            // 新位置之后的记录需要后移(dictId + 1)
+            for (StoreDictionary sibling : siblings) {
+                try {
+                    int siblingOrder = Integer.parseInt(sibling.getDictId());
+                    if (siblingOrder >= newOrder) {
+                        sibling.setDictId(String.valueOf(siblingOrder + 1));
+                        sibling.setUpdatedTime(new Date());
+                        storeDictionaryMapper.updateById(sibling);
+                    }
+                } catch (NumberFormatException e) {
+                    log.warn("无法解析dictId: {}", sibling.getDictId(), e);
+                }
+            }
+        } catch (NumberFormatException e) {
+            log.error("移入节点排序调整失败,dictId格式错误: newDictId={}", newDictId, e);
+        } catch (Exception e) {
+            log.error("移入节点排序调整失败", e);
+        }
+    }
+
+    /**
+     * 批量导入经营版块
+     *
+     * @param file Excel文件
+     * @return 导入结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public R<String> importBusinessSection(MultipartFile file) {
+        log.info("PlatformBusinessSectionServiceImpl.importBusinessSection fileName={}", 
+                file != null ? file.getOriginalFilename() : "null");
+        try {
+            if (file == null || file.isEmpty()) {
+                return R.fail("文件不能为空");
+            }
+
+            String fileName = file.getOriginalFilename();
+            if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) {
+                return R.fail("文件格式不正确,请上传Excel文件");
+            }
+
+            List<String> errorMessages = new ArrayList<>();
+            int successCount = 0;
+            int totalCount = 0;
+
+            // 使用POI读取Excel
+            try (InputStream inputStream = file.getInputStream();
+                 Workbook workbook = new XSSFWorkbook(inputStream)) {
+                Sheet sheet = workbook.getSheetAt(0);
+
+                // 获取表头
+                Row headerRow = sheet.getRow(0);
+                if (headerRow == null) {
+                    return R.fail("Excel文件格式不正确,缺少表头");
+                }
+
+                // 构建字段映射(表头名称 -> 列索引)
+                Map<String, Integer> headerMap = new HashMap<>();
+                Field[] fields = BusinessSectionExcelVo.class.getDeclaredFields();
+                for (int i = 0; i < headerRow.getLastCellNum(); i++) {
+                    Cell cell = headerRow.getCell(i);
+                    if (cell != null) {
+                        String headerName = getCellValueAsString(cell);
+                        if (StringUtils.isNotBlank(headerName)) {
+                            headerMap.put(headerName.trim(), i);
+                        }
+                    }
+                }
+
+                // 读取数据行
+                for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+                    Row row = sheet.getRow(rowIndex);
+                    if (row == null) {
+                        continue;
+                    }
+
+                    // 检查是否为空行
+                    boolean isEmptyRow = true;
+                    for (int i = 0; i < row.getLastCellNum(); i++) {
+                        Cell cell = row.getCell(i);
+                        if (cell != null && cell.getCellType() != CellType.BLANK) {
+                            String cellValue = getCellValueAsString(cell);
+                            if (StringUtils.isNotBlank(cellValue)) {
+                                isEmptyRow = false;
+                                break;
+                            }
+                        }
+                    }
+                    if (isEmptyRow) {
+                        continue;
+                    }
+
+                    totalCount++;
+                    BusinessSectionExcelVo excelVo = new BusinessSectionExcelVo();
+
+                    // 读取每个字段
+                    for (Field field : fields) {
+                        if (!field.isAnnotationPresent(ExcelHeader.class)) {
+                            continue;
+                        }
+                        ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
+                        String headerName = excelHeader.value();
+                        Integer colIndex = headerMap.get(headerName);
+                        if (colIndex == null) {
+                            continue;
+                        }
+
+                        Cell cell = row.getCell(colIndex);
+                        if (cell == null) {
+                            continue;
+                        }
+
+                        field.setAccessible(true);
+                        try {
+                            String cellValue = getCellValueAsString(cell);
+                            if (StringUtils.isNotBlank(cellValue)) {
+                                field.set(excelVo, cellValue.trim());
+                            }
+                        } catch (Exception e) {
+                            log.warn("读取字段{}失败:{}", headerName, e.getMessage());
+                        }
+                    }
+
+                    // 处理导入数据
+                    try {
+                        processImportData(excelVo, rowIndex + 1, errorMessages);
+                        successCount++;
+                    } catch (Exception e) {
+                        errorMessages.add(String.format("第%d行:%s", rowIndex + 1, e.getMessage()));
+                        log.error("导入第{}行数据失败", rowIndex + 1, e);
+                    }
+                }
+            }
+
+            // 构建返回消息
+            StringBuilder message = new StringBuilder();
+            message.append(String.format("导入完成:成功%d条,失败%d条", successCount, totalCount - successCount));
+            if (!errorMessages.isEmpty()) {
+                message.append("\n失败详情:\n");
+                int maxErrors = Math.min(errorMessages.size(), 10); // 最多显示10条错误
+                for (int i = 0; i < maxErrors; i++) {
+                    message.append(errorMessages.get(i)).append("\n");
+                }
+                if (errorMessages.size() > 10) {
+                    message.append(String.format("...还有%d条错误未显示", errorMessages.size() - 10));
+                }
+            }
+
+            if (successCount == 0) {
+                return R.fail(message.toString());
+            } else if (totalCount - successCount > 0) {
+                return R.success(message.toString());
+            } else {
+                return R.success(message.toString());
+            }
+        } catch (Exception e) {
+            log.error("导入经营版块失败", e);
+            return R.fail("导入失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 处理导入数据
+     *
+     * @param excelVo Excel数据对象
+     * @param rowIndex 行号
+     * @param errorMessages 错误消息列表
+     */
+    private void processImportData(BusinessSectionExcelVo excelVo, int rowIndex, List<String> errorMessages) {
+        // 校验必填字段
+        if (StringUtils.isBlank(excelVo.getFirstLevelName())) {
+            throw new IllegalArgumentException("一级分类名称不能为空");
+        }
+
+        String firstLevelName = excelVo.getFirstLevelName().trim();
+        String secondLevelName = StringUtils.isNotBlank(excelVo.getSecondLevelName()) 
+                ? excelVo.getSecondLevelName().trim() : null;
+        String thirdLevelName = StringUtils.isNotBlank(excelVo.getThirdLevelName()) 
+                ? excelVo.getThirdLevelName().trim() : null;
+
+        // 确定要创建的级别
+        if (StringUtils.isNotBlank(thirdLevelName)) {
+            // 创建三级分类
+            createOrUpdateLevel(firstLevelName, secondLevelName, thirdLevelName, 3, excelVo.getHidden(), errorMessages, rowIndex);
+        } else if (StringUtils.isNotBlank(secondLevelName)) {
+            // 创建二级分类
+            createOrUpdateLevel(firstLevelName, secondLevelName, null, 2, excelVo.getHidden(), errorMessages, rowIndex);
+        } else {
+            // 创建一级分类
+            createOrUpdateLevel(firstLevelName, null, null, 1, excelVo.getHidden(), errorMessages, rowIndex);
+        }
+    }
+
+    /**
+     * 创建或更新分类级别
+     *
+     * @param firstLevelName 一级分类名称
+     * @param secondLevelName 二级分类名称
+     * @param thirdLevelName 三级分类名称
+     * @param level 级别(1、2、3)
+     * @param hidden 状态
+     * @param errorMessages 错误消息列表
+     * @param rowIndex 行号
+     */
+    private void createOrUpdateLevel(String firstLevelName, String secondLevelName, String thirdLevelName,
+                                     int level, String hidden, List<String> errorMessages, int rowIndex) {
+        try {
+            // 查找或创建一级分类
+            StoreDictionary firstLevel = findOrCreateLevel(firstLevelName, 0, 0, hidden);
+            if (firstLevel == null) {
+                throw new IllegalArgumentException("创建一级分类失败");
+            }
+            if (level >= 2 && StringUtils.isNotBlank(secondLevelName)) {
+                // 查找或创建二级分类
+                StoreDictionary secondLevel = findOrCreateLevel(secondLevelName, firstLevel.getId(), 1, hidden);
+                if (secondLevel == null) {
+                    throw new IllegalArgumentException("创建二级分类失败");
+                }
+
+                if (level >= 3 && StringUtils.isNotBlank(thirdLevelName)) {
+                    // 查找或创建三级分类
+                    StoreDictionary thirdLevel = findOrCreateLevel(thirdLevelName, secondLevel.getId(), 2, hidden);
+                    if (thirdLevel == null) {
+                        throw new IllegalArgumentException("创建三级分类失败");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new IllegalArgumentException(e.getMessage());
+        }
+    }
+
+    /**
+     * 查找或创建分类
+     *
+     * @param dictDetail 分类名称
+     * @param parentId 父节点ID
+     * @param expectedLevel 期望的级别(用于校验)
+     * @param hidden 状态
+     * @return 分类对象
+     */
+    private StoreDictionary findOrCreateLevel(String dictDetail, Integer parentId, int expectedLevel, String hidden) {
+        // 查找是否存在
+        LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+        queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+        queryWrapper.eq(StoreDictionary::getDictDetail, dictDetail);
+
+        if (parentId == null || parentId == 0) {
+            queryWrapper.and(wrapper -> wrapper.isNull(StoreDictionary::getParentId)
+                    .or().eq(StoreDictionary::getParentId, 0));
+        } else {
+            queryWrapper.eq(StoreDictionary::getParentId, parentId);
+        }
+        
+        StoreDictionary existing = storeDictionaryMapper.selectOne(queryWrapper);
+        
+        if (existing != null) {
+            return existing;
+        }
+
+        // 创建新分类
+        StoreDictionary newDict = new StoreDictionary();
+        newDict.setTypeName("business_section");
+        newDict.setDictDetail(dictDetail);
+        // 一级为经营版块 ,二级为经营种类,三级为分类
+        if (expectedLevel == 0) {
+            newDict.setTypeDetail("经营板块");
+        } else if (expectedLevel == 1) {
+            newDict.setTypeDetail("经营种类");
+        } else if (expectedLevel == 2) {
+            newDict.setTypeDetail("分类");
+        }
+        newDict.setParentId(parentId == null ? 0 : parentId);
+        newDict.setHidden(StringUtils.isNotBlank(hidden) && hidden.equals("隐藏") ? 1 : 0);
+        newDict.setDeleteFlag(0);
+        newDict.setCreatedTime(new Date());
+
+        // 生成 dict_id
+        String maxDictId = getMaxDictIdByParentId(newDict.getParentId());
+        /*int nextDictId;
+        if (StringUtils.isNotBlank(sortOrder) && expectedLevel == 1) {
+            try {
+                nextDictId = Integer.parseInt(sortOrder);
+                // 如果指定的排序已存在,需要调整
+                String existingDictId = getDictIdByParentIdAndOrder(newDict.getParentId(), nextDictId);
+                if (existingDictId != null) {
+                    // 使用最大+1
+                    nextDictId = (maxDictId == null ? 0 : Integer.parseInt(maxDictId)) + 1;
+                }
+            } catch (NumberFormatException e) {
+                nextDictId = (maxDictId == null ? 0 : Integer.parseInt(maxDictId)) + 1;
+            }
+        } else {
+            nextDictId = (maxDictId == null ? 0 : Integer.parseInt(maxDictId)) + 1;
+        }*/
+        newDict.setDictId(String.valueOf(maxDictId == null ? 1 : Integer.parseInt(maxDictId) + 1));
+
+        boolean saved = this.save(newDict);
+        return saved ? newDict : null;
+    }
+
+    /**
+     * 根据parentId和排序获取dictId
+     *
+     * @param parentId 父节点ID
+     * @param order 排序
+     * @return dictId
+     */
+    private String getDictIdByParentIdAndOrder(Integer parentId, int order) {
+        LambdaQueryWrapper<StoreDictionary> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StoreDictionary::getTypeName, "business_section");
+        queryWrapper.eq(StoreDictionary::getDeleteFlag, 0);
+        queryWrapper.eq(StoreDictionary::getDictId, String.valueOf(order));
+        
+        if (parentId == null || parentId == 0) {
+            queryWrapper.and(wrapper -> wrapper.isNull(StoreDictionary::getParentId)
+                    .or().eq(StoreDictionary::getParentId, 0));
+        } else {
+            queryWrapper.eq(StoreDictionary::getParentId, parentId);
+        }
+        
+        StoreDictionary dict = storeDictionaryMapper.selectOne(queryWrapper);
+        return dict != null ? dict.getDictId() : null;
+    }
+
+    /**
+     * 获取单元格值(字符串格式)
+     *
+     * @param cell 单元格
+     * @return 字符串值
+     */
+    private String getCellValueAsString(Cell cell) {
+        if (cell == null) {
+            return null;
+        }
+        
+        switch (cell.getCellType()) {
+            case STRING:
+                return cell.getStringCellValue();
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return cell.getDateCellValue().toString();
+                } else {
+                    // 处理数字,避免科学计数法
+                    double numericValue = cell.getNumericCellValue();
+                    if (numericValue == (long) numericValue) {
+                        return String.valueOf((long) numericValue);
+                    } else {
+                        return String.valueOf(numericValue);
+                    }
+                }
+            case BOOLEAN:
+                return String.valueOf(cell.getBooleanCellValue());
+            case FORMULA:
+                return cell.getCellFormula();
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * 下载经营版块导入模板
+     *
+     * @param response HTTP响应
+     * @throws IOException IO异常
+     */
+    @Override
+    public void downloadTemplate(HttpServletResponse response) throws IOException {
+        log.info("PlatformBusinessSectionServiceImpl.downloadTemplate");
+        
+        XSSFWorkbook workbook = new XSSFWorkbook();
+        try {
+            Sheet sheet = workbook.createSheet("经营版块导入模板");
+
+            // 获取带有 @ExcelHeader 注解的字段
+            Field[] fields = BusinessSectionExcelVo.class.getDeclaredFields();
+            List<Field> excelFields = new ArrayList<>();
+            for (Field field : fields) {
+                if (field.isAnnotationPresent(ExcelHeader.class)) {
+                    excelFields.add(field);
+                }
+            }
+
+            // 创建表头样式
+            Font headerFont = workbook.createFont();
+            headerFont.setBold(true);
+            headerFont.setFontHeightInPoints((short) 12);
+            CellStyle headerCellStyle = workbook.createCellStyle();
+            headerCellStyle.setFont(headerFont);
+            headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
+            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+            headerCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+            headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+            headerCellStyle.setBorderBottom(BorderStyle.THIN);
+            headerCellStyle.setBorderTop(BorderStyle.THIN);
+            headerCellStyle.setBorderLeft(BorderStyle.THIN);
+            headerCellStyle.setBorderRight(BorderStyle.THIN);
+
+            // 创建表头
+            Row headerRow = sheet.createRow(0);
+            for (int i = 0; i < excelFields.size(); i++) {
+                Field field = excelFields.get(i);
+                ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
+                Cell cell = headerRow.createCell(i);
+                cell.setCellValue(excelHeader.value());
+                cell.setCellStyle(headerCellStyle);
+            }
+
+            // 设置列宽
+            sheet.setColumnWidth(0, 25 * 256); // 一级分类名称
+            sheet.setColumnWidth(1, 25 * 256); // 二级分类名称
+            sheet.setColumnWidth(2, 25 * 256); // 三级分类名称
+            sheet.setColumnWidth(3, 15 * 256); // 状态(隐藏/显示)
+
+
+
+            // 设置响应头(必须在获取输出流之前设置)
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String fileName = URLEncoder.encode("经营版块导入模板", "UTF-8").replaceAll("\\+", "%20");
+            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
+
+            // 输出到响应流
+            OutputStream outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+            outputStream.flush();
+        } finally {
+            // 确保 workbook 被正确关闭
+            if (workbook != null) {
+                try {
+                    workbook.close();
+                } catch (IOException e) {
+                    log.error("关闭workbook失败", e);
+                }
+            }
+        }
+    }
+}
+

+ 235 - 10
alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java

@@ -1,7 +1,6 @@
 package shop.alien.store.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
-import com.alibaba.fastjson2.util.DateUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -12,16 +11,17 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.geo.Point;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
+import org.springframework.http.*;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
+import org.springframework.web.client.RestTemplate;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartRequest;
 import shop.alien.entity.store.*;
@@ -40,14 +40,12 @@ import shop.alien.store.service.*;
 import shop.alien.store.util.CommonConstant;
 import shop.alien.store.util.FileUploadUtil;
 import shop.alien.store.util.GroupConstant;
+import shop.alien.store.util.ai.AiAuthTokenUtil;
 import shop.alien.store.util.ali.AliApi;
 import shop.alien.util.ali.AliOSSUtil;
 import shop.alien.util.common.DistanceUtil;
 import shop.alien.util.common.UniqueRandomNumGenerator;
-import shop.alien.util.common.constant.CouponStatusEnum;
-import shop.alien.util.common.constant.CouponTypeEnum;
-import shop.alien.util.common.constant.DiscountCouponEnum;
-import shop.alien.util.common.constant.OrderStatusEnum;
+import shop.alien.util.common.constant.*;
 
 import javax.annotation.Resource;
 import java.io.File;
@@ -59,6 +57,7 @@ import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.SignStyle;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
@@ -71,11 +70,14 @@ import java.util.stream.Collectors;
  * @author ssk
  * @since 2024-12-05
  */
+@Slf4j
 @Service
 @RequiredArgsConstructor
 @Transactional
 public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo> implements StoreInfoService {
 
+    private static final int DEFAULT_DISTANCE_METER = 1000;
+
     private final String DEFAULT_PASSWORD = "123456";
 
     private final StoreInfoMapper storeInfoMapper;
@@ -140,6 +142,12 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
 
     private final LifeBlacklistMapper lifeBlacklistMapper;
 
+    private final OcrImageUploadMapper ocrImageUploadMapper;
+
+    private final AiAuthTokenUtil aiAuthTokenUtil;
+
+    private final RestTemplate restTemplate;
+
     @Resource
     private StoreIncomeDetailsRecordService storeIncomeDetailsRecordService;
 
@@ -150,6 +158,9 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
     @Value("${spring.web.resources.excel-generate-path}")
     private String excelGeneratePath;
 
+    @Value("${third-party-identification.base-url}")
+    private String identificationPath;
+
     /**
      * 懒得查, 留着导出Excel
      */
@@ -1550,7 +1561,7 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
             List<String> storeIds = Arrays.asList(storeId.split(","));
             if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                 List<StoreBusinessInfo> storeBusinessInfos = storeBusinessInfoMapper.selectList(new LambdaQueryWrapper<StoreBusinessInfo>().in(StoreBusinessInfo::getStoreId, storeIds));
-                DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.HOUR_OF_DAY, 1, 2, java.time.format.SignStyle.NOT_NEGATIVE).appendLiteral(':').appendValue(ChronoField.MINUTE_OF_HOUR, 2).toFormatter();
+                DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.HOUR_OF_DAY, 1, 2, SignStyle.NOT_NEGATIVE).appendLiteral(':').appendValue(ChronoField.MINUTE_OF_HOUR, 2).toFormatter();
                 List<StoreBusinessInfo> list = storeBusinessInfos.stream().filter(item -> {
                     // 商家开门时间
                     LocalTime timeStart = LocalTime.parse(item.getEndTime(), formatter);
@@ -1630,7 +1641,7 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
             List<String> storeIds = Arrays.asList(storeId.split(","));
             if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                 List<StoreBusinessInfo> storeBusinessInfos = storeBusinessInfoMapper.selectList(new LambdaQueryWrapper<StoreBusinessInfo>().in(StoreBusinessInfo::getStoreId, storeIds));
-                DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.HOUR_OF_DAY, 1, 2, java.time.format.SignStyle.NOT_NEGATIVE).appendLiteral(':').appendValue(ChronoField.MINUTE_OF_HOUR, 2).toFormatter();
+                DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.HOUR_OF_DAY, 1, 2, SignStyle.NOT_NEGATIVE).appendLiteral(':').appendValue(ChronoField.MINUTE_OF_HOUR, 2).toFormatter();
                 List<StoreBusinessInfo> list = storeBusinessInfos.stream().filter(item -> {
                     // 商家开门时间
                     LocalTime timeStart = LocalTime.parse(item.getEndTime(), formatter);
@@ -2460,4 +2471,218 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
         }
         return result;
     }
+
+    /**
+     * web-分页查询店铺信息
+     *
+
+     * @return IPage<StoreInfoVo>
+     */
+    @Override
+    public List<StoreInfoVo> getMoreRecommendedStores(Double lon , Double lat, int subcategory, int threeLevelClassification) {
+        QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("a.delete_flag", 0).eq("b.delete_flag", 0).orderByDesc("a.created_time");
+        //如果查询未过期
+        // 获取当前时刻
+        Date currentDate = new Date();
+        // 获取当前日期和时间
+        Calendar calendar = Calendar.getInstance();
+        // 将时间设置为 0 点
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        // 加上 30 天
+        calendar.add(Calendar.DAY_OF_MONTH, 30);
+
+        List<StoreInfoVo> storeInfoVoList = storeInfoMapper.getMoreRecommendedStores(queryWrapper);
+        if (CollectionUtils.isEmpty(storeInfoVoList)) {
+            return Collections.emptyList();
+        }
+        // 提前查询所有需要的字典数据
+        List<StoreInfoVo> collect = storeInfoVoList.stream().filter(record -> StringUtils.isNotEmpty(record.getStoreType())).collect(Collectors.toList());
+        Set<String> allTypes = collect.stream().map(StoreInfoVo::getStoreType).flatMap(type -> Arrays.stream(type.split(","))).collect(Collectors.toSet());
+
+        List<StoreDictionary> storeDictionaries = storeDictionaryMapper.selectList(new LambdaQueryWrapper<StoreDictionary>().eq(StoreDictionary::getTypeName, "storeType").isNull(StoreDictionary::getParentId).in(!allTypes.isEmpty(), StoreDictionary::getDictId, allTypes));
+        Map<String, String> typeMap = storeDictionaries.stream().collect(Collectors.toMap(StoreDictionary::getDictId, StoreDictionary::getDictDetail));
+
+
+        // 计算平均分和评价
+        Map<Object, List<Map<String, Object>>> avgScoreMap = new HashMap<>();
+        Map<Integer, List<StoreComment>> commentMap = new HashMap<>();
+
+        avgScoreMap = storeEvaluationMapper.allStoreAvgScore().stream().collect(Collectors.groupingBy(o -> o.get("store_id")));
+        commentMap = storeCommentMapper.selectList(new QueryWrapper<StoreComment>().eq("business_type", "5").eq("delete_flag", 0)).stream().collect(Collectors.groupingBy(StoreComment::getStoreId));
+
+
+        for (StoreInfoVo record : storeInfoVoList) {
+            //处理类型
+            if (StringUtils.isNotEmpty(record.getStoreType())) {
+                String[] types = record.getStoreType().split(",");
+                List<String> typeDetails = Arrays.stream(types).map(typeMap::get).filter(Objects::nonNull).collect(Collectors.toList());
+                record.setStoreTypeStr(String.join(",", typeDetails));
+                record.setStoreTypeList(Arrays.asList(types));
+            }
+            //写经纬度
+            String[] split = record.getStorePosition().split(",");
+            record.setStorePositionLongitude(split[0]);
+            record.setStorePositionLatitude(split[1]);
+            //处理一下到期状态
+            Date expirationTime = record.getExpirationTime();
+            if (expirationTime != null) {
+                // 获取当前时间
+                Calendar now = Calendar.getInstance();
+                Date nowCurrentDate = now.getTime();
+                // 计算 30 天后的时间
+                now.add(Calendar.DAY_OF_YEAR, 30);
+                Date thirtyDaysLater = now.getTime();
+                // 比较两个日期
+                if (expirationTime.after(currentDate)) {
+                    record.setExpiredState("0");
+                    if ((expirationTime.after(nowCurrentDate) || expirationTime.equals(nowCurrentDate)) && expirationTime.before(thirtyDaysLater)) {
+                        record.setExpiredState("1");
+                    }
+                } else {
+                    record.setExpiredState("2");
+                }
+
+                // 获取当前时间
+                LocalDate nowLocal = LocalDate.now();
+                // 将 expirationTime 转换为 LocalDate
+                LocalDate expDate = expirationTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+                // 计算距离到期的天数
+                long daysToExpire = ChronoUnit.DAYS.between(nowLocal, expDate);
+                record.setDaysToExpire(daysToExpire);
+            }
+
+            // 设置店铺得分,设置店铺人均消费,设置总评论数
+            if (avgScoreMap.containsKey(String.valueOf(record.getId()))) {
+                record.setAvgScore(String.valueOf(avgScoreMap.get(String.valueOf(record.getId())).get(0).get("avg_score")));
+            }
+            // 设置店铺得分,设置店铺人均消费,设置总评论数
+            if (commentMap.containsKey(record.getId())) {
+                record.setTotalNum(String.valueOf(commentMap.get(record.getId()).size()));
+            }
+
+        }
+        if (lon == null || lat == null) {
+            log.warn("获取更多推荐店铺失败,经纬度为空");
+            return Collections.emptyList();
+        }
+
+        return filterStoresWithinDistance(storeInfoVoList, lon, lat);
+    }
+
+    /**
+     * 根据距离过滤并排序店铺列表
+     *
+     * @param storeInfoVoList 原始店铺列表
+     * @param lon             用户经度
+     * @param lat             用户纬度
+     * @return 距离范围内的店铺列表
+     */
+    private List<StoreInfoVo> filterStoresWithinDistance(List<StoreInfoVo> storeInfoVoList, double lon, double lat) {
+        List<StoreInfoVo> filteredList = storeInfoVoList.stream()
+                .filter(store -> isWithinDistance(store, lon, lat, StoreInfoServiceImpl.DEFAULT_DISTANCE_METER))
+                .sorted(Comparator.comparingDouble(StoreInfoVo::getDistance3))
+                .collect(Collectors.toList());
+
+        if (log.isInfoEnabled()) {
+            log.info("距离筛选完成,原始店铺数量={},筛选后店铺数量={},筛选距离={}米",
+                    storeInfoVoList.size(), filteredList.size(), StoreInfoServiceImpl.DEFAULT_DISTANCE_METER);
+        }
+        return filteredList;
+    }
+
+    /**
+     * 判断店铺是否在指定距离范围内
+     *
+     * @param store       店铺信息
+     * @param lon         用户经度
+     * @param lat         用户纬度
+     * @param maxDistance 最大距离(米)
+     * @return true 表示在范围内
+     */
+    private boolean isWithinDistance(StoreInfoVo store, double lon, double lat, int maxDistance) {
+        if (StringUtils.isEmpty(store.getStorePosition())) {
+            return false;
+        }
+
+        String[] positionArray = store.getStorePosition().split(",");
+        if (positionArray.length != 2) {
+            log.warn("店铺坐标格式异常,storeId={},storePosition={}", store.getId(), store.getStorePosition());
+            return false;
+        }
+
+        try {
+            double storeLon = Double.parseDouble(positionArray[0].trim());
+            double storeLat = Double.parseDouble(positionArray[1].trim());
+            double distanceMeters = DistanceUtil.haversineCalculateDistance(lon, lat, storeLon, storeLat) * 1000;
+            store.setDistance3(distanceMeters);
+            return distanceMeters <= maxDistance;
+        } catch (NumberFormatException ex) {
+            log.warn("店铺坐标解析失败,storeId={},storePosition={},error={}", store.getId(), store.getStorePosition(), ex.getMessage());
+            return false;
+        }
+    }
+
+    @Override
+    public Map<String, Object> getStoreOcrData(String storeId, String imageUrl) {
+        Map<String, Object> map = new HashMap<>();
+        LambdaQueryWrapper<OcrImageUpload> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(OcrImageUpload::getStoreId, storeId)
+                .eq(OcrImageUpload::getOcrType, OcrTypeEnum.BUSINESS_LICENSE.getCode());
+        OcrImageUpload ocrImageUploads = ocrImageUploadMapper.selectOne(queryWrapper);
+        if(ocrImageUploads== null){
+            throw new RuntimeException("未找到OCI识别数据!");
+        }
+        String accessToken = aiAuthTokenUtil.getAccessToken();
+
+        HttpHeaders aiHeaders = new HttpHeaders();
+        aiHeaders.setContentType(MediaType.APPLICATION_JSON);
+        aiHeaders.set("Authorization", "Bearer " + accessToken);
+        Map<String, Object> jsonBody = new HashMap<>();
+        List<String> imageUrls = new ArrayList<>();
+        imageUrls.add(imageUrl);
+        jsonBody.put("image_urls", imageUrls);
+        String ocrResult = ocrImageUploads.getOcrResult();
+        JSONObject jsonObject = JSONObject.parseObject(ocrResult);
+        jsonBody.put("merchant_name", jsonObject.get("companyName"));
+
+        HttpEntity<Map<String, Object>> request = new HttpEntity<>(jsonBody, aiHeaders);
+        ResponseEntity<String> response = null;
+        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
+        factory.setConnectTimeout(5000);
+        factory.setReadTimeout(60000);
+        restTemplate.setRequestFactory(factory);
+        try {
+            response = restTemplate.postForEntity(identificationPath, request, String.class);
+            if (response.getStatusCodeValue() != 200) {
+                throw new RuntimeException("AI内容审核接口调用失败 http状态:" + response.getStatusCode());
+            }
+
+        } catch (Exception e) {
+            throw new RuntimeException("AI接口调用失败");
+        }
+        com.alibaba.fastjson2.JSONObject responseNode = com.alibaba.fastjson2.JSONObject.parseObject(response.getBody());
+        if (responseNode == null) {
+            throw new RuntimeException("AI接口调用失败,响应内容为空");
+        } else {
+            Integer code = responseNode.getInteger("code");
+            if (code == 200) {
+                Map<String, Object> dataMap = (Map<String, Object>) responseNode.get("data");
+                if (Objects.nonNull(dataMap)) {
+                    // 获取match_results(JSON中是数组,反序列化为List<Map>)
+                    List<Map<String, Object>> matchResults = (List<Map<String, Object>>) dataMap.get("match_results");
+                    map.put("overall_match", dataMap.get("overall_match"));
+                    if (Objects.nonNull(matchResults) && !matchResults.isEmpty()) {
+                        map.put("match_reason", matchResults.get(0).get("match_reason"));
+                    }
+                }
+            } else {
+                throw new RuntimeException("AI接口调用失败,错误码: " + code);
+            }
+        }
+        return map;
+    }
 }

+ 29 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreStaffConfigServiceImpl.java

@@ -168,4 +168,33 @@ public class StoreStaffConfigServiceImpl implements StoreStaffConfigService {
         }
         return storeStaffConfigMapper.update(null, lambdaUpdateWrapper);
     }
+
+    @Override
+    public IPage<StoreStaffConfig> queryStaffList(Integer page, Integer size, Integer storeId, String status) {
+        IPage<StoreStaffConfig> storePage = new Page<>(page, size);
+        QueryWrapper<StoreStaffConfig> queryWrapper = new QueryWrapper<>();
+        // 按照店铺ID查询
+        if (storeId != null && storeId > 0) {
+            queryWrapper.eq("store_id", storeId);
+        }
+        // 如果状态不为空,则进行精确匹配查询
+        if (StringUtils.isNotEmpty(status)) {
+            queryWrapper.eq("status", status);
+        }
+        // 只查询未删除的记录
+        queryWrapper.eq("delete_flag", 0);
+        queryWrapper.orderByDesc("created_time");
+        return storeStaffConfigMapper.selectPage(storePage, queryWrapper);
+    }
+
+    @Override
+    public StoreStaffConfig queryStaffDetail(Integer id) {
+        if (id == null || id <= 0) {
+            return null;
+        }
+        QueryWrapper<StoreStaffConfig> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("id", id);
+        queryWrapper.eq("delete_flag", 0);
+        return storeStaffConfigMapper.selectOne(queryWrapper);
+    }
 }

+ 4 - 4
alien-util/src/main/java/shop/alien/util/ai/AiAuthTokenUtil.java → alien-store/src/main/java/shop/alien/store/util/ai/AiAuthTokenUtil.java

@@ -1,4 +1,4 @@
-package shop.alien.util.ai;
+package shop.alien.store.util.ai;
 
 import com.alibaba.fastjson2.JSONObject;
 import lombok.RequiredArgsConstructor;
@@ -21,13 +21,13 @@ public class AiAuthTokenUtil {
 
     private final RestTemplate restTemplate;
 
-    @Value("${third-party-login.base-url:http://192.168.2.250:9000/ai/user-auth-core/api/v1/auth/login}")
+    @Value("${third-party-login.base-url}")
     private String loginUrl;
 
-    @Value("${third-party-user-name.base-url:UdUser}")
+    @Value("${third-party-user-name.base-url}")
     private String userName;
 
-    @Value("${third-party-pass-word.base-url:123456}")
+    @Value("${third-party-pass-word.base-url}")
     private String passWord;
 
     /**