# 获取店铺详细信息接口文档 ## 概述 本文档描述了从 `alien-store`(app端商户)迁移到 `alien-store-platform`(web端商户)的获取店铺详细信息接口。 ## 接口详情 ### 获取店铺详细信息 **接口描述**:获取指定店铺的完整详细信息,包括基本信息、图片、菜单、营业时间、地铁距离等。 #### 原接口 - **服务**:alien-store(app端商户) - **路径**:`GET /alienStore/store/info/getDetail?id=102` - **Controller**:`StoreInfoController.getDetail()` - **Service**:`StoreInfoServiceImpl.getDetail()` #### 新接口 - **服务**:alien-store-platform(web端商户) - **路径**:`GET /alienStorePlatform/storeManage/getStoreDetail?id=102` - **Controller**:`StoreManageController.getStoreDetail()` - **Service**:`StoreManageServiceImpl.getStoreDetail()` #### 请求参数 **Query 参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Integer | 是 | 店铺ID | **请求示例**: ``` GET /alienStorePlatform/storeManage/getStoreDetail?id=102 ``` #### 响应参数 **成功响应**: ```json { "code": 200, "msg": "success", "data": { "id": 102, "storeName": "张三的餐厅", "storeAddress": "河南省郑州市金水区某某路123号", "storeTel": "0371-12345678", "storeBlurb": "这是一家美味的餐厅", "storePosition": "113.625368,34.746599", "businessStatus": 1, "businessStatusStr": "营业中", "storeArea": 3, "storeAreaStr": "100-200平米", "storeCapacity": 50, "businessSection": 1, "businessSectionName": "餐饮", "businessTypes": "1,2,3", "businessTypesName": "中餐,西餐,快餐", "expirationTime": "2025-12-31 23:59:59", "expirationFlag": 1, "headImgUrl": "https://example.com/head.jpg", "inletsUrl": [ "https://example.com/inlet1.jpg", "https://example.com/inlet2.jpg" ], "albumUrl": [ "https://example.com/album1.jpg", "https://example.com/album2.jpg", "https://example.com/album3.jpg" ], "recommendUrl": [ { "id": 1, "dishName": "招牌菜", "imgUrl": "https://example.com/dish1.jpg", "dishPrice": "38.00", "dishesUnit": "份", "imgSort": 1 } ], "menuUrl": [ { "id": 2, "dishName": "普通菜品", "imgUrl": "https://example.com/dish2.jpg", "dishPrice": "28.00", "dishesUnit": "份", "imgSort": 1 } ], "storeLabel": { "id": 1, "storeId": 102, "labelContent": "环境优雅,服务周到" }, "storeBusinessInfo": [ { "id": 1, "storeId": 102, "weekDay": "周一", "startTime": "09:00", "endTime": "22:00" }, { "id": 2, "storeId": 102, "weekDay": "周二", "startTime": "09:00", "endTime": "22:00" } ], "logoutFlagUser": 0, "subwayName": "某某地铁站", "distance2": 1.5 }, "success": true } ``` **失败响应(店铺不存在)**: ```json { "code": 500, "msg": "店铺不存在", "data": null, "success": false } ``` **失败响应(其他错误)**: ```json { "code": 500, "msg": "查询失败: {错误信息}", "data": null, "success": false } ``` #### 响应字段说明 ##### 基本信息字段 | 字段名 | 类型 | 说明 | |--------|------|------| | id | Integer | 店铺ID | | storeName | String | 店铺名称 | | storeAddress | String | 店铺地址 | | storeTel | String | 店铺电话 | | storeBlurb | String | 店铺简介 | | storePosition | String | 经纬度(格式:经度,纬度)| | businessStatus | Integer | 营业状态代码 | | businessStatusStr | String | 营业状态文字 | | storeArea | Integer | 店铺面积代码 | | storeAreaStr | String | 店铺面积文字 | | storeCapacity | Integer | 容纳人数 | | businessSection | Integer | 经营板块ID | | businessSectionName | String | 经营板块名称 | | businessTypes | String | 经营种类IDs(逗号分隔)| | businessTypesName | String | 经营种类名称(逗号分隔)| | expirationTime | DateTime | 到期时间 | | expirationFlag | Integer | 是否到期(0:已到期, 1:未到期)| ##### 图片相关字段 | 字段名 | 类型 | 说明 | |--------|------|------| | headImgUrl | String | 店铺头像URL | | inletsUrl | List | 入口图URL列表(按imgSort排序)| | albumUrl | List | 相册URL列表(按imgSort排序)| ##### 菜单相关字段 | 字段名 | 类型 | 说明 | |--------|------|------| | recommendUrl | List | 推荐菜列表(按imgSort排序)| | menuUrl | List | 普通菜单列表(按imgSort排序)| **StoreMenuVo 字段说明**: | 字段名 | 类型 | 说明 | |--------|------|------| | id | Integer | 菜品ID | | dishName | String | 菜品名称 | | imgUrl | String | 菜品图片URL | | dishPrice | String | 菜品价格 | | dishesUnit | String | 单位 | | imgSort | Integer | 排序号 | ##### 其他信息字段 | 字段名 | 类型 | 说明 | |--------|------|------| | storeLabel | StoreLabel | 店铺标签信息 | | storeBusinessInfo | List | 营业时间列表 | | logoutFlagUser | Integer | 关联用户注销状态(0:正常, 1:已注销)| | subwayName | String | 最近地铁站名称 | | distance2 | double | 到最近地铁站的距离(公里)| #### 业务逻辑 1. **店铺存在性检查**: - 根据店铺ID查询 `store_info` 表 - 如果不存在,返回 `null` 2. **基本信息查询**: - 通过 `StoreInfoMapper.getStoreInfo()` 获取店铺基本信息 - 包含营业状态、店铺面积的字典翻译 3. **到期状态判断**: - 如果 `expirationTime` 存在: - 当前时间 > 到期时间 → `expirationFlag=0`(已到期) - 当前时间 ≤ 到期时间 → `expirationFlag=1`(未到期) - 如果 `expirationTime` 不存在 → `expirationFlag=1`(默认未到期) 4. **图片查询**(按类型): - **imgType=1**:入口图 - **imgType=2**:相册 - **imgType=10**:店铺头像 - 所有图片按 `imgSort` 排序 5. **菜单查询**(按是否推荐): - **isRecommend=1**:推荐菜 - **isRecommend=0**:普通菜单 - 所有菜品按 `imgSort` 排序 6. **店铺标签查询**: - 从 `store_label` 表查询标签内容 7. **营业时间查询**: - 从 `store_business_info` 表查询完整的营业时间列表 8. **商户用户状态查询**: - 查询关联的 `store_user` 记录 - 获取用户的注销状态 `logoutFlag` 9. **地铁距离计算**: - 调用高德地图API查询最近的地铁站 - 使用 Haversine 公式计算店铺到地铁站的距离 - 如果查询失败或无地铁站,设置 `distance2=0` --- ## 技术实现 ### 依赖的 Mapper - `StoreInfoMapper`:查询店铺基本信息 - `StoreImgMapper`:查询图片 - `StoreMenuMapper`:查询菜单 - `StoreLabelMapper`:查询标签 - `StoreBusinessInfoMapper`:查询营业时间 - `StoreUserMapper`:查询商户用户 ### 依赖的工具类 - `GaoDeMapApiUtil`:高德地图API调用 - `getNearbySubway(longitude, latitude)`:查询附近地铁站 - `DistanceUtil`:距离计算 - `haversineCalculateDistance(lng1, lat1, lng2, lat2)`:计算两点距离 ### 核心代码片段 ```java @Override public StoreMainInfoVo getStoreDetail(Integer id) { // 1. 检查店铺是否存在 StoreInfo storeInfo = storeInfoMapper.selectById(id); if (storeInfo == null) { return null; } // 2. 获取基本信息(包含字典翻译) StoreMainInfoVo storeMainInfoVo = storeInfoMapper.getStoreInfo(id); // 3. 判断到期状态 if (ObjectUtils.isNotEmpty(storeMainInfoVo.getExpirationTime())) { if (new Date().after(storeMainInfoVo.getExpirationTime())) { storeMainInfoVo.setExpirationFlag(0); // 已到期 } else { storeMainInfoVo.setExpirationFlag(1); // 未到期 } } else { storeMainInfoVo.setExpirationFlag(1); // 默认未到期 } // 4-8. 查询图片、菜单、标签、营业时间等信息 // ... // 9. 计算地铁距离 JSONObject nearbySubway = gaoDeMapApiUtil.getNearbySubway(longitude, latitude); String subwayName = nearbySubway.getString("name"); storeMainInfoVo.setSubwayName(subwayName); String location = nearbySubway.getString("location"); if (StringUtils.isNotEmpty(location)) { double distance = DistanceUtil.haversineCalculateDistance( subwayLng, subwayLat, storeLng, storeLat); storeMainInfoVo.setDistance2(distance); } return storeMainInfoVo; } ``` --- ## Nacos 配置要求 需要在 Nacos 的 `alien-store-platform.yml` 中添加以下配置: ```yaml # 高德地图API配置 gaode: key: "你的高德地图API Key" geoListUrl: "https://restapi.amap.com/v3/assistant/inputtips?keywords=%s&key=%s&city=%s" getDistrict: "https://restapi.amap.com/v3/config/district?key=%s&keywords=%s&subdistrict=1" getNearbyUrl: "https://restapi.amap.com/v3/place/around?location=%s&types=150500&radius=5000&key=%s&sortrule=distance" ``` ### 配置说明 - `gaode.key`:高德地图开放平台的 API Key - `gaode.geoListUrl`:输入提示接口URL - `gaode.getDistrict`:行政区划接口URL - `gaode.getNearbyUrl`:周边搜索接口URL - `types=150500`:地铁站类型代码 - `radius=5000`:搜索半径5000米 - `sortrule=distance`:按距离排序 --- ## 测试建议 ### 测试用例 1:正常查询 ```bash curl -X GET http://localhost:8080/alienStorePlatform/storeManage/getStoreDetail?id=102 ``` **期望结果**: - 返回完整的店铺详细信息 - 包含所有图片、菜单、营业时间等 - `expirationFlag` 根据实际到期时间正确设置 - `distance2` 显示到最近地铁站的距离 ### 测试用例 2:店铺不存在 ```bash curl -X GET http://localhost:8080/alienStorePlatform/storeManage/getStoreDetail?id=999999 ``` **期望结果**: ```json { "code": 500, "msg": "店铺不存在", "data": null, "success": false } ``` ### 测试用例 3:已到期店铺 - 查询一个 `expiration_time` 在当前时间之前的店铺 **期望结果**: - `expirationFlag` 为 `0` ### 测试用例 4:无地铁站区域 - 查询一个偏远区域的店铺(附近5000米内无地铁站) **期望结果**: - `subwayName` 为空字符串 - `distance2` 为 `0` --- ## 相关文件 ### Controller 层 - `alien-store-platform/src/main/java/shop/alien/storeplatform/controller/StoreManageController.java` ### Service 层 - `alien-store-platform/src/main/java/shop/alien/storeplatform/service/StoreManageService.java` - `alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/StoreManageServiceImpl.java` ### 工具类 - `alien-store-platform/src/main/java/shop/alien/storeplatform/util/GaoDeMapApiUtil.java` - `alien-util/src/main/java/shop/alien/util/map/DistanceUtil.java` ### Entity/Mapper 层 - `alien-entity/src/main/java/shop/alien/entity/store/vo/StoreMainInfoVo.java` - `alien-entity/src/main/java/shop/alien/entity/store/vo/StoreMenuVo.java` - `alien-entity/src/main/java/shop/alien/mapper/StoreInfoMapper.java` - `alien-entity/src/main/java/shop/alien/mapper/StoreImgMapper.java` - `alien-entity/src/main/java/shop/alien/mapper/StoreMenuMapper.java` - `alien-entity/src/main/java/shop/alien/mapper/StoreLabelMapper.java` - `alien-entity/src/main/java/shop/alien/mapper/StoreBusinessInfoMapper.java` - `alien-entity/src/main/java/shop/alien/mapper/StoreUserMapper.java` --- ## 注意事项 ### 1. 图片类型说明(imgType) | imgType | 说明 | 用途 | |---------|------|------| | 1 | 入口图 | 店铺门面照片 | | 2 | 相册 | 店铺环境照片 | | 10 | 头像 | 店铺logo/头像 | | 14 | 营业执照 | 资质文件 | | 15 | 合同 | 合同文件 | | 25 | 经营许可证 | 资质文件 | ### 2. 到期状态判断逻辑 ``` if (expirationTime != null) { if (当前时间 > expirationTime) { expirationFlag = 0 // 已到期 } else { expirationFlag = 1 // 未到期 } } else { expirationFlag = 1 // 无到期时间,默认未到期 } ``` ### 3. 地铁距离计算 - 使用 Haversine 公式计算球面距离 - 返回单位:**公里**(千米) - 精度:保留两位小数 - 失败处理:如果计算失败,`distance2` 设为 `0` ### 4. 图片和菜单排序 - 所有图片URL列表按 `imgSort` 字段升序排序 - 推荐菜和普通菜单按 `imgSort` 字段升序排序 - 确保前端展示顺序与后台设置一致 ### 5. 性能优化建议 - ⚠️ 单次查询涉及多个表和多次数据库访问 - ⚠️ 地铁距离计算需要调用外部API - 建议添加Redis缓存(键:`store:detail:{id}`,过期时间:1小时) - 地铁信息可单独缓存(变动频率低) --- ## 版本记录 | 版本 | 日期 | 说明 | 作者 | |------|------|------|------| | 1.0.0 | 2025-01-xx | 初始版本,迁移店铺详情查询功能 | ssk | --- ## 联系方式 如有问题,请联系: - 开发团队:Alien Cloud Team - 邮箱:dev@alien.shop