Преглед изворни кода

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

panzhilin пре 2 недеља
родитељ
комит
535a5b366a

+ 3 - 1
alien-entity/src/main/java/shop/alien/entity/store/StoreInfo.java

@@ -243,11 +243,13 @@ public class StoreInfo {
     @TableField("business_classify_name")
     private String businessClassifyName;
 
+
+
     @ApiModelProperty(value = "是否提供餐食")
     @TableField("meals_flag")
     private Integer  mealsFlag;
 
-    @ApiModelProperty(value = "娱乐经营许可证状态 字典 foodLicenceStatus")
+    @ApiModelProperty(value = "娱乐经营许可证状态")
     @TableField("entertainment_licence_status")
     private Integer entertainmentLicenceStatus;
 

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

@@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 import java.util.Date;
 
@@ -16,6 +17,7 @@ import java.util.Date;
  * @Description: 员工管理
  */
 @Data
+@EqualsAndHashCode(callSuper = false)
 @JsonInclude
 @TableName("store_staff_config")
 @ApiModel(value = "StoreStaffConfig对象", description = "员工管理")
@@ -89,4 +91,13 @@ public class StoreStaffConfig extends Model<StoreStaffConfig> {
     @ApiModelProperty(value = "修改人ID")
     @TableField("updated_user_id")
     private Integer updatedUserId;
+
+    @ApiModelProperty(value = "置顶状态, 0:未置顶, 1:已置顶")
+    @TableField("top_status")
+    private Integer topStatus;
+
+    @ApiModelProperty(value = "置顶时间")
+    @TableField("top_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date topTime;
 }

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

@@ -114,6 +114,7 @@ public class StoreInfoDto {
     private String businessTypeValue;
 
     @ApiModelProperty(value = "经营种类集合")
+    @JsonDeserialize(using = StringToListDeserializer.class)
     private List<String> businessTypesList;
 
     @ApiModelProperty(value = "经营板块id(词典表 键为 business_section)")
@@ -130,9 +131,11 @@ public class StoreInfoDto {
     private String userAccount;
 
     @ApiModelProperty(value = "营业执照图片地址")
+    @JsonDeserialize(using = StringToListDeserializer.class)
     private List<String> businessLicenseAddress;
 
     @ApiModelProperty(value = "合同图片地址")
+    @JsonDeserialize(using = StringToListDeserializer.class)
     private List<String> contractImageList;
 
     @ApiModelProperty(value = "经营许可证图片地址")
@@ -184,6 +187,7 @@ public class StoreInfoDto {
     private Date foodLicenceExpirationTime;
 
     @ApiModelProperty(value = "分类id(词典表 键为 business_classify)(多个ID用逗号拼接)")
+    @JsonDeserialize(using = StringToListDeserializer.class)
     private List<String> businessClassify;
 
     @ApiModelProperty(value = "分类名称")

+ 9 - 5
alien-entity/src/main/java/shop/alien/mapper/LifeFansMapper.java

@@ -15,7 +15,8 @@ import java.util.List;
 @Mapper
 public interface LifeFansMapper extends BaseMapper<LifeFans> {
 
-    @Select("select foll.*,lb.id blackListid, if(isnull(fans.id), 0, 1) isFollowMe, 1 as isFollowThis,  " +
+    @Select("select MAX(foll.id) id, MAX(foll.name) name, MAX(foll.image) image, foll.phoneId, MAX(foll.blurb) blurb, MAX(foll.blockedType) blockedType, MAX(foll.blockedId) blockedId, MAX(foll.username) username, MAX(foll.accountBlurb) accountBlurb, " +
+            "  MAX(lb.id) blackListid, MAX(if(isnull(fans.id), 0, 1)) isFollowMe, 1 as isFollowThis,  " +
             "  (select count(1) from life_fans where fans_id= foll.phoneId and delete_flag =0) followNum, " +
             "  (select count(1) from life_fans where followed_id= foll.phoneId and delete_flag =0) fansNum from ( " +
             "    with follow as (   " +
@@ -63,7 +64,8 @@ public interface LifeFansMapper extends BaseMapper<LifeFans> {
             "left join life_fans fans on fans.fans_id = foll.phoneId and fans.followed_id = #{fansId} and fans.delete_flag = 0 ")
     List<LifeFansVo> getMyFollowedAll(@Param("fansId") String fansId);
 
-    @Select("select foll.*,lb.id blackListid, if(isnull(fans.id), 0, 1) isFollowThis, 1 as isFollowMe, " +
+    @Select("select MAX(foll.id) id, MAX(foll.name) name, MAX(foll.image) image, foll.phoneId, MAX(foll.blurb) blurb, MAX(foll.blockedType) blockedType, MAX(foll.blockedId) blockedId, " +
+            "  MAX(lb.id) blackListid, MAX(if(isnull(fans.id), 0, 1)) isFollowThis, 1 as isFollowMe, " +
             "    (select count(1) from life_fans fans2 where fans2.followed_id = foll.phoneId and fans2.delete_flag = 0) fansNum, " +
             "    (select count(1) from life_fans fans3 where fans3.fans_id = foll.phoneId and fans3.delete_flag = 0) followNum " +
             "from ( " +
@@ -169,7 +171,8 @@ public interface LifeFansMapper extends BaseMapper<LifeFans> {
             "${ew.customSqlSegment}")
     IPage<LifeFansVo> getMyStoreFans(IPage<LifeFansVo> iPage, @Param("fansId") String fansId, @Param(Constants.WRAPPER) QueryWrapper<LifeFansVo> wrapper);
 
-    @Select("select foll.*, if(isnull(fans.id), 0, 1) isFollowThis, 1 as isFollowMe, " +
+    @Select("select MAX(foll.id) id, MAX(foll.name) name, MAX(foll.image) image, foll.phoneId, MAX(foll.blurb) blurb, " +
+            "  MAX(if(isnull(fans.id), 0, 1)) isFollowThis, 1 as isFollowMe, " +
             "       (select count(1) from life_fans fans2 where fans2.followed_id = foll.phoneId and fans2.delete_flag = 0) fansNum, " +
             "       (select count(1) from life_fans fans3 where fans3.fans_id = foll.phoneId and fans3.delete_flag = 0) followNum " +
             " from ( " +
@@ -187,7 +190,8 @@ public interface LifeFansMapper extends BaseMapper<LifeFans> {
             "${ew.customSqlSegment} ")
     IPage<LifeFansVo> getMyUserFans(IPage<LifeFansVo> iPage, @Param("fansId") String fansId, @Param(Constants.WRAPPER) QueryWrapper<LifeFansVo> wrapper);
 
-    @Select("select foll.*, lb.id blackListid, 1 as isFollowThis, 1 as isFollowMe, " +
+    @Select("select MAX(foll.id) id, MAX(foll.name) name, MAX(foll.image) image, foll.phoneId, MAX(foll.blurb) blurb, MAX(foll.blockedType) blockedType, MAX(foll.blockedId) blockedId, MAX(foll.username) username, MAX(foll.accountBlurb) accountBlurb, " +
+            "  MAX(lb.id) blackListid, 1 as isFollowThis, 1 as isFollowMe, " +
             "       (select count(1) from life_fans fans2 where fans2.followed_id = foll.phoneId and fans2.delete_flag = 0) fansNum, " +
             "       (select count(1) from life_fans fans3 where fans3.fans_id = foll.phoneId and fans3.delete_flag = 0) followNum " +
             "from ( " +
@@ -213,7 +217,7 @@ public interface LifeFansMapper extends BaseMapper<LifeFans> {
             "${ew.customSqlSegment} ")
     IPage<LifeFansVo> getMutualAttention(IPage<LifeFansVo> iPage, @Param("fansId") String fansId, @Param("blockerType") String blockerType, @Param("blockerId") String blockerId, @Param(Constants.WRAPPER) QueryWrapper<LifeFansVo> wrapper);
 
-    @Select("select foll.*, 1 as isFollowThis, 1 as isFollowMe, " +
+    @Select("select MAX(foll.id) id, MAX(foll.name) name, MAX(foll.image) image, foll.phoneId, MAX(foll.blurb) blurb, 1 as isFollowThis, 1 as isFollowMe, " +
             "       (select count(1) from life_fans fans2 where fans2.followed_id = foll.phoneId and fans2.delete_flag = 0) fansNum, " +
             "       (select count(1) from life_fans fans3 where fans3.fans_id = foll.phoneId and fans3.delete_flag = 0) followNum " +
             "from ( " +

+ 22 - 1
alien-store/src/main/java/shop/alien/store/controller/StoreInfoController.java

@@ -1051,7 +1051,28 @@ public class StoreInfoController {
             return R.fail("获取推荐店铺失败,请稍后重试");
         }
     }
-
+    /**
+     * 根据business_classify字段获取字典表数据实现UI图中的功能
+     * RESTful风格:GET /store/info/business-classifies
+     * 返回扁平化的分类列表,用于多选分类功能
+     *
+     * @param parentId 父分类ID(可选),如果提供则只返回该父分类下的子分类
+     * @return R<List<StoreDictionaryVo>> 分类列表(扁平化,仅子分类)
+     */
+    @ApiOperation("获取店铺分类信息)")
+    @ApiOperationSupport(order = 19)
+    @GetMapping("/business-classifies")
+    public R<List<StoreDictionaryVo>> getBusinessClassifyData(
+            @RequestParam(value = "parentId", required = false) Integer parentId) {
+        log.info("StoreInfoController.getBusinessClassifyData?parentId={}", parentId);
+        try {
+            List<StoreDictionaryVo> result = storeInfoService.getBusinessClassifyData(parentId);
+            return R.data(result);
+        } catch (Exception e) {
+            log.error("获取business_classify分类数据异常", e);
+            return R.fail("获取分类数据失败,请稍后重试");
+        }
+    }
 
 
     @ApiOperation(value = "获取banner图详情")

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

@@ -78,6 +78,26 @@ public class StoreStaffConfigController {
         return R.data(s);
     }
 
+    @ApiOperation("删除员工")
+    @ApiOperationSupport(order = 4)
+    @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "主键id", dataType = "Integer", paramType = "query", required = true)})
+    @GetMapping("/deleteStaffConfig")
+    public R<Integer> deleteStaffConfig(Integer id) {
+        log.info("StoreStaffConfigController.deleteStaffConfig?id={}", id);
+        return R.data(storeStaffConfigService.deleteStaffConfig(id));
+    }
+
+    @ApiOperation("置顶员工")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键id", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "topStatus", value = "置顶状态 0-取消置顶, 1-置顶", dataType = "Integer", paramType = "query", required = true)
+    })
+    @GetMapping("/setTopStatus")
+    public R<Integer> setTopStatus(Integer id, Integer topStatus) {
+        log.info("StoreStaffConfigController.setTopStatus?id={},topStatus={}", id, topStatus);
+        return R.data(storeStaffConfigService.setTopStatus(id, topStatus));
+    }
     /**
      * 员工列表查询接口(用户端)
      *

+ 10 - 1
alien-store/src/main/java/shop/alien/store/service/StoreInfoService.java

@@ -309,7 +309,7 @@ public interface StoreInfoService extends IService<StoreInfo> {
      * @param distance    距离范围(单位:公里)
      * @param sortType    排序模式(1:智能排序,2:好评优先,3:距离优先)
      * @param businessType 店铺类型(KTV=3、洗浴汗蒸=4、按摩足浴=5,酒吧需要查询字典表),可选
-     * @param categoryId 字典表id,根据此id查询经营板块、经营种类、分类并匹配店铺,可选
+     * @param categoryId  分类ID(二级或三级分类的dictId,从getAllBusinessSection接口获取),可选
      * @param pageNum     页码
      * @param pageSize    页容
      * @return IPage<StoreInfoVo> 分页的门店信息列表
@@ -352,6 +352,15 @@ public interface StoreInfoService extends IService<StoreInfo> {
      */
     List<StoreInfoVo> getRecommendedStores(String businessSection, String businessTypes, String businessClassify, Double lon, Double lat);
 
+    /**
+     * 获取三级分类数据
+     * 根据二级分类ID获取该分类下的三级分类
+     *
+     * @param parentId 二级分类ID
+     * @return List<StoreDictionaryVo> 三级分类列表
+     */
+    List<StoreDictionaryVo> getBusinessClassifyData(Integer parentId);
+
 
 
 

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

@@ -19,6 +19,24 @@ public interface StoreStaffConfigService {
     String staffConfigExport(String status) throws IOException;
 
     /**
+     * 删除员工
+     *
+     * @param id
+     * @return
+     */
+    Integer deleteStaffConfig(Integer id);
+
+    /**
+     * 置顶员工
+     *
+     * @param id 员工ID
+     * @param topStatus 置顶状态 0-未置顶, 1-置顶
+     * @return
+     */
+    Integer setTopStatus(Integer id, Integer topStatus);
+
+
+    /**
      * 员工列表查询
      *
      * @param page    分页页数

+ 8 - 5
alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java

@@ -13,6 +13,7 @@ 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.*;
@@ -42,6 +43,7 @@ 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.constant.CouponStatusEnum;
@@ -59,6 +61,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,13 +74,13 @@ import java.util.stream.Collectors;
  * @author ssk
  * @since 2024-12-05
  */
-@Service
 @Slf4j
+@Service
 @RequiredArgsConstructor
 @Transactional
 public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo> implements StoreInfoService {
-    private static final int DEFAULT_DISTANCE_METER = 1000;
 
+    private static final int DEFAULT_DISTANCE_METER = 1000;
 
     private final String DEFAULT_PASSWORD = "123456";
 
@@ -2827,14 +2830,14 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
         if (lon == null || lat == null) {
             throw new IllegalArgumentException("经纬度参数不能为空");
         }
-
+        
         // 智能检测:如果参数可能传反了(lat超出范围但lon在范围内),给出提示
         if (Math.abs(lat) > 90 && Math.abs(lon) <= 90) {
             throw new IllegalArgumentException(
                     String.format("参数可能传反了!当前值: lon=%s, lat=%s。经度范围: [-180, 180],纬度范围: [-90, 90]。请检查参数顺序。", lon, lat)
             );
         }
-
+        
         // 校验经纬度范围:经度 [-180, 180],纬度 [-90, 90]
         if (lon < -180 || lon > 180) {
             throw new IllegalArgumentException("经度参数超出有效范围 [-180, 180],当前值: " + lon);
@@ -3012,7 +3015,7 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
 
         // 提取所有门店ID
         List<Integer> storeIds = storeInfoVoList.stream().map(StoreInfoVo::getId).collect(Collectors.toList());
-
+        
         if (CollectionUtils.isEmpty(storeIds)) {
             // 如果没有符合条件的店铺,返回空结果
             IPage<StoreInfoVo> emptyPage = new Page<>(pageNum, pageSize);

+ 62 - 3
alien-store/src/main/java/shop/alien/store/service/impl/StoreStaffConfigServiceImpl.java

@@ -1,6 +1,7 @@
 package shop.alien.store.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -51,18 +52,54 @@ public class StoreStaffConfigServiceImpl implements StoreStaffConfigService {
         IPage<StoreStaffConfig> storePage = new Page<>(page, size);
         QueryWrapper<StoreStaffConfig> queryWrapper = new QueryWrapper<>();
         queryWrapper.like(null != status && !status.isEmpty(), "status", status);
-        queryWrapper.orderByDesc("created_time");
+        // 排序规则:先按置顶状态降序(置顶的在前),再按置顶时间降序,最后按创建时间降序
+        queryWrapper.orderByDesc("top_status", "top_time", "created_time");
         return storeStaffConfigMapper.selectPage(storePage, queryWrapper);
     }
 
     @Override
     public int addOrUpdateStaffConfig(StoreStaffConfig storeStaffConfig) {
-        if (StringUtils.isEmpty(storeStaffConfig.getId().toString())) {
+        // 判断是新增还是更新:id为null或0或负数表示新增
+        // 注意:新增时不应该传入id,如果传入了非0的id,需要先查询是否存在
+        Integer id = storeStaffConfig.getId();
+        
+        if (id == null || id == 0) {
+            // 新增操作:id为null或0
             Date nowDate = new Date(System.currentTimeMillis());
             storeStaffConfig.setCreatedTime(nowDate);
+            // 设置删除标记为0(未删除)- 必须设置,否则可能插入失败
+            if (storeStaffConfig.getDeleteFlag() == null) {
+                storeStaffConfig.setDeleteFlag(0);
+            }
+            // 如果状态为空,设置默认状态为待审核(0)
+            if (StringUtils.isEmpty(storeStaffConfig.getStatus())) {
+                storeStaffConfig.setStatus("0");
+            }
+            // 新增时,确保id为null,让数据库自动生成
+            storeStaffConfig.setId(null);
             return storeStaffConfigMapper.insert(storeStaffConfig);
         } else {
-            return storeStaffConfigMapper.updateById(storeStaffConfig);
+            // 更新操作:id不为null且不为0
+            // 先查询记录是否存在,如果不存在则转为新增
+            StoreStaffConfig existing = storeStaffConfigMapper.selectById(id);
+            if (existing == null) {
+                // 记录不存在,转为新增操作
+                storeStaffConfig.setId(null); // 重置id,让数据库自动生成
+                Date nowDate = new Date(System.currentTimeMillis());
+                storeStaffConfig.setCreatedTime(nowDate);
+                // 设置删除标记为0(未删除)
+                if (storeStaffConfig.getDeleteFlag() == null) {
+                    storeStaffConfig.setDeleteFlag(0);
+                }
+                // 如果状态为空,设置默认状态为待审核(0)
+                if (StringUtils.isEmpty(storeStaffConfig.getStatus())) {
+                    storeStaffConfig.setStatus("0");
+                }
+                return storeStaffConfigMapper.insert(storeStaffConfig);
+            } else {
+                // 记录存在,执行更新
+                return storeStaffConfigMapper.updateById(storeStaffConfig);
+            }
         }
     }
 
@@ -110,6 +147,28 @@ public class StoreStaffConfigServiceImpl implements StoreStaffConfigService {
         return aliOSSUtil.uploadFile(new File(filePath), "excel/" + fileName + ".xlsx");
     }
 
+    @Override
+    public Integer deleteStaffConfig(Integer id) {
+        // 使用 MyBatis-Plus 的逻辑删除,会自动将 deleteFlag 设置为 1
+        // 因为实体类使用了 @TableLogic 注解
+        return storeStaffConfigMapper.deleteById(id);
+    }
+
+    @Override
+    public Integer setTopStatus(Integer id, Integer topStatus) {
+        if (id == null || topStatus == null) {
+            return 0;
+        }
+        LambdaUpdateWrapper<StoreStaffConfig> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+        lambdaUpdateWrapper.eq(StoreStaffConfig::getId, id);
+        lambdaUpdateWrapper.set(StoreStaffConfig::getTopStatus, topStatus);
+        if (topStatus == 0) {
+            lambdaUpdateWrapper.set(StoreStaffConfig::getTopTime, null);
+        } else {
+            lambdaUpdateWrapper.set(StoreStaffConfig::getTopTime, new Date());
+        }
+        return storeStaffConfigMapper.update(null, lambdaUpdateWrapper);
+    }
 
     @Override
     public IPage<StoreStaffConfig> queryStaffList(Integer page, Integer size, Integer storeId, String status) {