# 获取店铺详细信息接口文档

## 概述

本文档描述了从 `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<String> | 入口图URL列表（按imgSort排序）|
| albumUrl | List<String> | 相册URL列表（按imgSort排序）|

##### 菜单相关字段

| 字段名 | 类型 | 说明 |
|--------|------|------|
| recommendUrl | List<StoreMenuVo> | 推荐菜列表（按imgSort排序）|
| menuUrl | List<StoreMenuVo> | 普通菜单列表（按imgSort排序）|

**StoreMenuVo 字段说明**：

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | Integer | 菜品ID |
| dishName | String | 菜品名称 |
| imgUrl | String | 菜品图片URL |
| dishPrice | String | 菜品价格 |
| dishesUnit | String | 单位 |
| imgSort | Integer | 排序号 |

##### 其他信息字段

| 字段名 | 类型 | 说明 |
|--------|------|------|
| storeLabel | StoreLabel | 店铺标签信息 |
| storeBusinessInfo | List<StoreBusinessInfo> | 营业时间列表 |
| 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

