Procházet zdrojové kódy

会员管理代码

wwh před 2 týdny
rodič
revize
3ca827ae1f

+ 0 - 28
baqing-shop/src/main/java/com/ruoyi/web/modules/content/controller/HomeBannerAppController.java

@@ -1,28 +0,0 @@
1
-package com.ruoyi.web.modules.content.controller;
2
-
3
-import org.springframework.beans.factory.annotation.Autowired;
4
-import org.springframework.web.bind.annotation.GetMapping;
5
-import org.springframework.web.bind.annotation.RequestMapping;
6
-import org.springframework.web.bind.annotation.RestController;
7
-import com.ruoyi.common.annotation.Anonymous;
8
-import com.ruoyi.common.core.controller.BaseController;
9
-import com.ruoyi.common.core.domain.AjaxResult;
10
-import com.ruoyi.web.modules.content.service.IBannerService;
11
-
12
-/**
13
- * C 端首页 Banner
14
- */
15
-@RestController
16
-@RequestMapping("/api/home")
17
-public class HomeBannerAppController extends BaseController
18
-{
19
-    @Autowired
20
-    private IBannerService bannerService;
21
-
22
-    @Anonymous
23
-    @GetMapping("/banners")
24
-    public AjaxResult banners()
25
-    {
26
-        return success(bannerService.listBannersForApp());
27
-    }
28
-}

+ 3 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/home/constant/HomeConstants.java

@@ -11,4 +11,7 @@ public final class HomeConstants
11 11
 
12 12
     /** 热销商品展示条数上限 */
13 13
     public static final int HOT_GOODS_LIMIT = 6;
14
+
15
+    /** Banner 启用且未删记录查询上限 */
16
+    public static final int BANNER_LIST_LIMIT = 50;
14 17
 }

+ 8 - 1
baqing-shop/src/main/java/com/ruoyi/web/modules/home/controller/HomeAppController.java

@@ -10,7 +10,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
10 10
 import com.ruoyi.web.modules.home.service.IHomeAppService;
11 11
 
12 12
 /**
13
- * C 端商城首页(类目导航、热销商品)
13
+ * C 端商城首页(Banner、类目导航、热销商品)
14 14
  */
15 15
 @RestController
16 16
 @RequestMapping("/api/home")
@@ -19,6 +19,13 @@ public class HomeAppController extends BaseController
19 19
     @Autowired
20 20
     private IHomeAppService homeAppService;
21 21
 
22
+    @Anonymous
23
+    @GetMapping("/banners")
24
+    public AjaxResult banners()
25
+    {
26
+        return success(homeAppService.listBanners());
27
+    }
28
+
22 29
     @Anonymous
23 30
     @GetMapping("/categories")
24 31
     public AjaxResult categories()

+ 6 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/home/mapper/HomeAppMapper.java

@@ -2,6 +2,7 @@ package com.ruoyi.web.modules.home.mapper;
2 2
 
3 3
 import java.util.List;
4 4
 import org.apache.ibatis.annotations.Param;
5
+import com.ruoyi.web.modules.home.vo.HomeBannerVO;
5 6
 import com.ruoyi.web.modules.home.vo.HomeCategoryNavVO;
6 7
 import com.ruoyi.web.modules.home.vo.HomeHotGoodsVO;
7 8
 
@@ -10,6 +11,11 @@ import com.ruoyi.web.modules.home.vo.HomeHotGoodsVO;
10 11
  */
11 12
 public interface HomeAppMapper
12 13
 {
14
+    /**
15
+     * C 端 Banner 列表(启用且未删)
16
+     */
17
+    List<HomeBannerVO> selectBannersForHome(@Param("limit") int limit);
18
+
13 19
     /**
14 20
      * 平台一级类目导航(show=1)
15 21
      */

+ 6 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/home/service/IHomeAppService.java

@@ -1,6 +1,7 @@
1 1
 package com.ruoyi.web.modules.home.service;
2 2
 
3 3
 import java.util.List;
4
+import com.ruoyi.web.modules.home.vo.HomeBannerVO;
4 5
 import com.ruoyi.web.modules.home.vo.HomeCategoryNavVO;
5 6
 import com.ruoyi.web.modules.home.vo.HomeHotGoodsVO;
6 7
 
@@ -9,6 +10,11 @@ import com.ruoyi.web.modules.home.vo.HomeHotGoodsVO;
9 10
  */
10 11
 public interface IHomeAppService
11 12
 {
13
+    /**
14
+     * Banner 轮播列表
15
+     */
16
+    List<HomeBannerVO> listBanners();
17
+
12 18
     /**
13 19
      * 平台一级类目导航
14 20
      */

+ 8 - 0
baqing-shop/src/main/java/com/ruoyi/web/modules/home/service/impl/HomeAppServiceImpl.java

@@ -7,6 +7,7 @@ import org.springframework.stereotype.Service;
7 7
 import com.ruoyi.web.modules.home.constant.HomeConstants;
8 8
 import com.ruoyi.web.modules.home.mapper.HomeAppMapper;
9 9
 import com.ruoyi.web.modules.home.service.IHomeAppService;
10
+import com.ruoyi.web.modules.home.vo.HomeBannerVO;
10 11
 import com.ruoyi.web.modules.home.vo.HomeCategoryNavVO;
11 12
 import com.ruoyi.web.modules.home.vo.HomeHotGoodsVO;
12 13
 
@@ -19,6 +20,13 @@ public class HomeAppServiceImpl implements IHomeAppService
19 20
     @Autowired
20 21
     private HomeAppMapper homeAppMapper;
21 22
 
23
+    @Override
24
+    public List<HomeBannerVO> listBanners()
25
+    {
26
+        List<HomeBannerVO> list = homeAppMapper.selectBannersForHome(HomeConstants.BANNER_LIST_LIMIT);
27
+        return list != null ? list : Collections.emptyList();
28
+    }
29
+
22 30
     @Override
23 31
     public List<HomeCategoryNavVO> listPlatformLevel1Nav()
24 32
     {

+ 11 - 0
baqing-shop/src/main/resources/mapper/home/HomeAppMapper.xml

@@ -2,6 +2,17 @@
2 2
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 3
 <mapper namespace="com.ruoyi.web.modules.home.mapper.HomeAppMapper">
4 4
 
5
+    <select id="selectBannersForHome" resultType="com.ruoyi.web.modules.home.vo.HomeBannerVO">
6
+        select banner_id as bannerId,
7
+               banner_image as bannerImage,
8
+               sort_no as sortNo
9
+        from biz_home_banner
10
+        where del_flag = '0'
11
+          and enable_flag = '1'
12
+        order by sort_no asc, create_time asc
13
+        limit #{limit}
14
+    </select>
15
+
5 16
     <select id="selectPlatformLevel1Nav" resultType="com.ruoyi.web.modules.home.vo.HomeCategoryNavVO">
6 17
         select category_id as categoryId,
7 18
                category_name as categoryName,

+ 0 - 67
baqing-shop/src/test/java/com/ruoyi/web/modules/content/controller/HomeBannerAppControllerTest.java

@@ -1,67 +0,0 @@
1
-package com.ruoyi.web.modules.content.controller;
2
-
3
-import static org.mockito.Mockito.when;
4
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
5
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
6
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
7
-import java.util.Collections;
8
-import org.junit.jupiter.api.BeforeEach;
9
-import org.junit.jupiter.api.Test;
10
-import org.junit.jupiter.api.extension.ExtendWith;
11
-import org.mockito.InjectMocks;
12
-import org.mockito.Mock;
13
-import org.mockito.junit.jupiter.MockitoExtension;
14
-import org.springframework.test.web.servlet.MockMvc;
15
-import org.springframework.test.web.servlet.setup.MockMvcBuilders;
16
-import com.ruoyi.web.modules.content.service.IBannerService;
17
-import com.ruoyi.web.modules.content.vo.HomeBannerAppVO;
18
-
19
-/**
20
- * C 端首页 Banner 接口测试(BAN-API-016~)
21
- */
22
-@ExtendWith(MockitoExtension.class)
23
-class HomeBannerAppControllerTest
24
-{
25
-    @Mock
26
-    private IBannerService bannerService;
27
-
28
-    @InjectMocks
29
-    private HomeBannerAppController controller;
30
-
31
-    private MockMvc mockMvc;
32
-
33
-    @BeforeEach
34
-    void setUp()
35
-    {
36
-        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
37
-    }
38
-
39
-    @Test
40
-    void banners_returns200() throws Exception
41
-    {
42
-        HomeBannerAppVO vo = new HomeBannerAppVO();
43
-        vo.setBannerId(1L);
44
-        vo.setBannerImage("/profile/upload/b1.jpg");
45
-        vo.setSortNo(0);
46
-        when(bannerService.listBannersForApp()).thenReturn(Collections.singletonList(vo));
47
-
48
-        mockMvc.perform(get("/api/home/banners"))
49
-                .andExpect(status().isOk())
50
-                .andExpect(jsonPath("$.code").value(200))
51
-                .andExpect(jsonPath("$.data[0].bannerId").value(1))
52
-                .andExpect(jsonPath("$.data[0].bannerImage").value("/profile/upload/b1.jpg"))
53
-                .andExpect(jsonPath("$.data[0].sortNo").value(0));
54
-    }
55
-
56
-    @Test
57
-    void banners_emptyList() throws Exception
58
-    {
59
-        when(bannerService.listBannersForApp()).thenReturn(Collections.emptyList());
60
-
61
-        mockMvc.perform(get("/api/home/banners"))
62
-                .andExpect(status().isOk())
63
-                .andExpect(jsonPath("$.code").value(200))
64
-                .andExpect(jsonPath("$.data").isArray())
65
-                .andExpect(jsonPath("$.data").isEmpty());
66
-    }
67
-}

+ 30 - 0
baqing-shop/src/test/java/com/ruoyi/web/modules/home/controller/HomeAppControllerTest.java

@@ -16,6 +16,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
16 16
 import org.springframework.test.web.servlet.MockMvc;
17 17
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
18 18
 import com.ruoyi.web.modules.home.service.IHomeAppService;
19
+import com.ruoyi.web.modules.home.vo.HomeBannerVO;
19 20
 import com.ruoyi.web.modules.home.vo.HomeCategoryNavVO;
20 21
 import com.ruoyi.web.modules.home.vo.HomeHotGoodsVO;
21 22
 
@@ -39,6 +40,35 @@ class HomeAppControllerTest
39 40
         mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
40 41
     }
41 42
 
43
+    @Test
44
+    void banners_returns200WithoutToken() throws Exception
45
+    {
46
+        HomeBannerVO vo = new HomeBannerVO();
47
+        vo.setBannerId(1L);
48
+        vo.setBannerImage("/profile/upload/b1.jpg");
49
+        vo.setSortNo(0);
50
+        when(homeAppService.listBanners()).thenReturn(Collections.singletonList(vo));
51
+
52
+        mockMvc.perform(get("/api/home/banners"))
53
+                .andExpect(status().isOk())
54
+                .andExpect(jsonPath("$.code").value(200))
55
+                .andExpect(jsonPath("$.data[0].bannerId").value(1))
56
+                .andExpect(jsonPath("$.data[0].bannerImage").value("/profile/upload/b1.jpg"))
57
+                .andExpect(jsonPath("$.data[0].sortNo").value(0));
58
+    }
59
+
60
+    @Test
61
+    void banners_emptyList() throws Exception
62
+    {
63
+        when(homeAppService.listBanners()).thenReturn(Collections.emptyList());
64
+
65
+        mockMvc.perform(get("/api/home/banners"))
66
+                .andExpect(status().isOk())
67
+                .andExpect(jsonPath("$.code").value(200))
68
+                .andExpect(jsonPath("$.data").isArray())
69
+                .andExpect(jsonPath("$.data").isEmpty());
70
+    }
71
+
42 72
     @Test
43 73
     void categories_returns200WithoutToken() throws Exception
44 74
     {

+ 47 - 0
baqing-shop/src/test/java/com/ruoyi/web/modules/home/service/HomeAppServiceImplTest.java

@@ -17,6 +17,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
17 17
 import com.ruoyi.web.modules.home.constant.HomeConstants;
18 18
 import com.ruoyi.web.modules.home.mapper.HomeAppMapper;
19 19
 import com.ruoyi.web.modules.home.service.impl.HomeAppServiceImpl;
20
+import com.ruoyi.web.modules.home.vo.HomeBannerVO;
20 21
 import com.ruoyi.web.modules.home.vo.HomeCategoryNavVO;
21 22
 import com.ruoyi.web.modules.home.vo.HomeHotGoodsVO;
22 23
 
@@ -32,6 +33,43 @@ class HomeAppServiceImplTest
32 33
     @InjectMocks
33 34
     private HomeAppServiceImpl homeAppService;
34 35
 
36
+    @Test
37
+    void listBanners_delegatesWithLimit()
38
+    {
39
+        HomeBannerVO b1 = banner(1L, "/pic/b1.jpg", 0);
40
+        when(homeAppMapper.selectBannersForHome(HomeConstants.BANNER_LIST_LIMIT))
41
+                .thenReturn(Collections.singletonList(b1));
42
+
43
+        List<HomeBannerVO> result = homeAppService.listBanners();
44
+
45
+        verify(homeAppMapper).selectBannersForHome(HomeConstants.BANNER_LIST_LIMIT);
46
+        assertEquals(1, result.size());
47
+        assertEquals("/pic/b1.jpg", result.get(0).getBannerImage());
48
+    }
49
+
50
+    @Test
51
+    void listBanners_emptyListWhenNoData()
52
+    {
53
+        when(homeAppMapper.selectBannersForHome(HomeConstants.BANNER_LIST_LIMIT))
54
+                .thenReturn(Collections.emptyList());
55
+
56
+        List<HomeBannerVO> result = homeAppService.listBanners();
57
+
58
+        assertNotNull(result);
59
+        assertTrue(result.isEmpty());
60
+    }
61
+
62
+    @Test
63
+    void listBanners_nullMapperResultReturnsEmpty()
64
+    {
65
+        when(homeAppMapper.selectBannersForHome(HomeConstants.BANNER_LIST_LIMIT)).thenReturn(null);
66
+
67
+        List<HomeBannerVO> result = homeAppService.listBanners();
68
+
69
+        assertNotNull(result);
70
+        assertTrue(result.isEmpty());
71
+    }
72
+
35 73
     @Test
36 74
     void listPlatformLevel1Nav_returnsVisibleCategories()
37 75
     {
@@ -222,6 +260,15 @@ class HomeAppServiceImplTest
222 260
         return vo;
223 261
     }
224 262
 
263
+    private static HomeBannerVO banner(Long id, String image, int sortNo)
264
+    {
265
+        HomeBannerVO vo = new HomeBannerVO();
266
+        vo.setBannerId(id);
267
+        vo.setBannerImage(image);
268
+        vo.setSortNo(sortNo);
269
+        return vo;
270
+    }
271
+
225 272
     private static HomeHotGoodsVO hotGoods(Long goodsId, String goodsSn, int salesProxy)
226 273
     {
227 274
         HomeHotGoodsVO vo = new HomeHotGoodsVO();

+ 23 - 10
doc/平台后台/内容管理/首页banner设置/首页banner设置技术方案.md

@@ -21,17 +21,20 @@
21 21
 
22 22
 ```text
23 23
 baqing-shop
24
-├── com.ruoyi.web.modules.banner.controller.BannerController          # 平台端
25
-└── com.ruoyi.web.modules.banner.controller.HomeBannerAppController   # C 端首页
26
-    ├── domain.BizHomeBanner
27
-    ├── mapper.BizHomeBannerMapper
28
-    ├── service.IBannerService
29
-    └── constant.BannerConstants
24
+├── com.ruoyi.web.modules.content
25
+│   ├── controller.BannerController              # 平台端 /agri/banner
26
+│   ├── domain.BizHomeBanner
27
+│   ├── mapper.BizHomeBannerMapper
28
+│   ├── service.IBannerService
29
+│   └── constant.BannerConstants
30
+├── com.ruoyi.web.modules.home
31
+│   └── controller.HomeAppController             # C 端 GET /api/home/banners
32
+│       └── mapper.HomeAppMapper                 # 直读 biz_home_banner(Anonymous)
30 33
 sql/
31 34
 └── biz_home_banner.sql
32 35
 ```
33 36
 
34
-> **无** Facade 对外暴露(BN8~BN10:与供给链/订单无耦合);后续协议模块可并列 `com.ruoyi.web.modules.content`。
37
+> **无** Facade 对外暴露(BN8~BN10:与供给链/订单无耦合)。C 端 Banner **列表** 由 **home** 模块提供;平台 CRUD 仍走 **content** 模块 `IBannerService`。
35 38
 
36 39
 ### 1.2 业务链
37 40
 
@@ -40,7 +43,7 @@ biz_home_banner(本模块 · 平台维护)
40 43
41 44
         ├── 平台 Web ── CRUD / 行内改序
42 45
43
-        └── C 端首页 ── GET /api/home/banners(Anonymous)
46
+        └── C 端首页 ── GET /api/home/banners(Anonymous · `HomeAppController`
44 47
                 └── 前端过滤无效图、零条隐藏轮播区(BN13,客户端)
45 48
 ```
46 49
 
@@ -56,7 +59,7 @@ biz_home_banner(本模块 · 平台维护)
56 59
 | 类型 | 说明 |
57 60
 |------|------|
58 61
 | **无 Java Facade** | 其他模块 **不依赖** Banner |
59
-| **C 端 HTTP** | 仅 `HomeBannerAppController` 提供首页列表 |
62
+| **C 端 HTTP** | `HomeAppController`(`com.ruoyi.web.modules.home`)提供 `GET /api/home/banners` |
60 63
 
61 64
 ### 1.4 状态联动
62 65
 
@@ -368,10 +371,20 @@ listForApp → enable_flag=1 AND del_flag=0 ORDER BY sort_no
368 371
 | 文档 | 版本 |
369 372
 |------|------|
370 373
 | 首页banner设置功能需求.md | v1.0.1 |
374
+| 商城首页技术方案.md | v1.1 |
371 375
 | 商品服务管理技术方案.md | v1.0.1 |
372 376
 | 会员管理技术方案.md | v1.0 |
373 377
 | 关联需求分析.md | v1.2 |
374 378
 
375 379
 ---
376 380
 
377
-*文档版本:v1.0 · MySQL 5.7.39 · RuoYi v3.9.2-springboot2 · 关联《首页banner设置功能需求.md》v1.0.1*
381
+## 11. 修订记录
382
+
383
+| 版本 | 说明 |
384
+|------|------|
385
+| **v1.0** | 首版 |
386
+| **v1.0.1** | C 端 `GET /api/home/banners` 落位 **`home.HomeAppController`**;平台 CRUD 仍 **content**;修正包路径 |
387
+
388
+---
389
+
390
+*文档版本:v1.0.1 · MySQL 5.7.39 · RuoYi v3.9.2-springboot2 · 关联《首页banner设置功能需求.md》v1.0.1*

+ 34 - 23
doc/消费者APP/商城首页/商城首页技术方案.md

@@ -21,26 +21,31 @@
21 21
 
22 22
 ```text
23 23
 baqing-shop/src/main/java/com/ruoyi/web/modules/home/
24
-├── controller/HomeAppController.java       # /api/home/categories、/api/home/hot-goods
24
+├── controller/HomeAppController.java       # /api/home/banners、/categories、/hot-goods
25 25
 ├── service/IHomeAppService.java
26 26
 ├── service/impl/HomeAppServiceImpl.java
27
+├── mapper/HomeAppMapper.java
28
+├── vo/HomeBannerVO.java
27 29
 ├── vo/HomeCategoryNavVO.java
28 30
 ├── vo/HomeHotGoodsVO.java
29 31
 └── constant/HomeConstants.java
30 32
 
31
-已有(content 模块,保持不变):
32
-└── com.ruoyi.web.modules.content.controller.HomeBannerAppController
33
-        GET /api/home/banners
33
+resources/mapper/home/
34
+└── HomeAppMapper.xml                         # biz_home_banner / biz_goods_category / biz_goods 只读 SQL
34 35
 
35
-resources/mapper/home/          # 可选:若 SQL 不扩展现有 Mapper,则新增 HomeGoodsMapper.xml
36
+平台 Banner CRUD(content 模块,保持不变):
37
+└── com.ruoyi.web.modules.content
38
+        ├── controller/BannerController          # /agri/banner
39
+        ├── service/IBannerService               # 平台维护
40
+        └── mapper/BizHomeBannerMapper
36 41
 ```
37 42
 
38
-> **说明:** Banner **不迁入** home 包,继续由 `IBannerService.listBannersForApp()` 提供;home 模块仅 **类目导航 + 热销**。
43
+> **说明:** C 端首页 **三读接口** 均归 `home` 包;Banner 列表由 `HomeAppMapper.selectBannersForHome` 直读 `biz_home_banner`(**不经过** `IBannerService`)。平台 CRUD 仍走 content 模块
39 44
 
40 45
 ### 1.2 协作链
41 46
 
42 47
 ```text
43
-biz_home_banner ──► GET /api/home/banners          (content · 已实现)
48
+biz_home_banner ──► GET /api/home/banners          (home · 已实现)
44 49
 biz_goods_category(shop_id IS NULL, level=1)──► GET /api/home/categories
45 50
 biz_goods + biz_shop ──► GET /api/home/hot-goods   (Top6)
46 51
 
@@ -63,8 +68,8 @@ biz_goods + biz_shop ──► GET /api/home/hot-goods   (Top6)
63 68
 
64 69
 | 接口 | 本模块用法 |
65 70
 |------|------------|
66
-| **`IBannerService`** | **不经过** home Service;独立 Controller |
67
-| **`IPlatformCategoryService`** | 可复用查询逻辑;C 端建议 **专用 SQL**(仅 `show_flag=1` 一级) |
71
+| **`IBannerService`** | **C 端不调用**;仅平台 `/agri/banner` CRUD 使用 |
72
+| **`IPlatformCategoryService`** | 可复用查询逻辑;C 端 **专用 SQL**(`HomeAppMapper`,仅 `show_flag=1` 一级) |
68 73
 | **`ICategoryFacade`** | 详情/下单用 `isCategoryVisible`;**首页类目 SQL 已过滤 show** |
69 74
 | **`IGoodsFacade` / 商品详情** | 首页 **不调用**;详情页可购校验 |
70 75
 
@@ -147,22 +152,23 @@ ALTER TABLE `biz_goods`
147 152
 
148 153
 | 方法 | 路径 | 提供方 | 说明 |
149 154
 |------|------|--------|------|
150
-| GET | `/banners` | `HomeBannerAppController`(**已有**) | Banner 列表 |
151
-| GET | `/categories` | `HomeAppController`(**新增**) | 平台一级类目导航 |
152
-| GET | `/hot-goods` | `HomeAppController`(**新增**) | 热销 Top6 |
155
+| GET | `/banners` | `HomeAppController`(**已实现**) | Banner 列表 |
156
+| GET | `/categories` | `HomeAppController`(**已实现**) | 平台一级类目导航 |
157
+| GET | `/hot-goods` | `HomeAppController`(**已实现**) | 热销 Top6 |
153 158
 
154 159
 **本期不提供:** `GET /api/home/index` 聚合接口、搜索 API、下拉刷新专用接口。
155 160
 
156 161
 ### 3.2 Banner `GET /api/home/banners`
157 162
 
158
-**已实现。** 详见《首页banner设置技术方案.md》§4.1。
163
+**已实现**(`home` 模块 · `HomeAppMapper.selectBannersForHome`)。平台维护规则见《首页banner设置技术方案.md》§4.1。
159 164
 
160 165
 | 项 | 说明 |
161 166
 |----|------|
162
-| SQL | `enable_flag=1 AND del_flag=0 ORDER BY sort_no, create_time` |
167
+| SQL | `enable_flag=1 AND del_flag=0 ORDER BY sort_no, create_time LIMIT 50` |
168
+| 常量 | `HomeConstants.BANNER_LIST_LIMIT = 50` |
163 169
 | 前端 | 无效图跳过、零条隐藏轮播区(BN13);点击预览大图 |
164 170
 
165
-**`data` 元素:**
171
+**`data` 元素:** `HomeBannerVO[]`
166 172
 
167 173
 | 字段 | 类型 | 说明 |
168 174
 |------|------|------|
@@ -257,16 +263,19 @@ LIMIT 6
257 263
 
258 264
 ```text
259 265
 HomeAppController
266
+    → IHomeAppService.listBanners()
260 267
     → IHomeAppService.listPlatformLevel1Nav()
261 268
     → IHomeAppService.listHotGoods()
262 269
 
263 270
 HomeAppServiceImpl
264
-    → BizGoodsCategoryMapper.selectPlatformLevel1Visible()   # 新增方法
265
-    → BizGoodsMapper.selectHotGoodsForHome(6)                 # 新增方法
271
+    → HomeAppMapper.selectBannersForHome(50)
272
+    → HomeAppMapper.selectPlatformLevel1Nav()
273
+    → HomeAppMapper.selectHotGoodsForHome(6)
266 274
 ```
267 275
 
268 276
 | 方法 | 说明 |
269 277
 |------|------|
278
+| `listBanners()` | 转 `HomeBannerVO`;SQL 过滤启用且未删 |
270 279
 | `listPlatformLevel1Nav()` | 转 `HomeCategoryNavVO`;`categoryPic` 空时原样返回(前端占位图) |
271 280
 | `listHotGoods()` | 转 `HomeHotGoodsVO`;`shopName` 来自 JOIN |
272 281
 
@@ -293,7 +302,7 @@ HomeAppServiceImpl
293 302
 | HM1 | 热销 SQL **全平台**;无 `shop_id` 入参 |
294 303
 | HM2 | `@Anonymous` |
295 304
 | HM3~HM-S2 | 无搜索 API;前端占位 |
296
-| HM4 | `/banners` → BannerService |
305
+| HM4 | `/banners` → `HomeAppMapper` 直读 `biz_home_banner` |
297 306
 | HM5~HM6 | `/categories`:`shop_id IS NULL` + level=1 + show=1 |
298 307
 | HM7 | 跳转由 **C 端路由** 承担;本模块只出 `categoryId` |
299 308
 | HM8~HM12 | `/hot-goods`:LIMIT 6 + 排序 + 字段 VO |
@@ -321,10 +330,11 @@ HomeAppServiceImpl
321 330
 
322 331
 | 项 | 状态 |
323 332
 |----|------|
324
-| `GET /api/home/banners` | **已实现**(content 模块) |
325
-| `GET /api/home/categories` | **待实现** |
326
-| `GET /api/home/hot-goods` | **待实现** |
327
-| `com.ruoyi.web.modules.home` 包 | **待创建** |
333
+| `GET /api/home/banners` | **已实现**(`home` 模块) |
334
+| `GET /api/home/categories` | **已实现** |
335
+| `GET /api/home/hot-goods` | **已实现** |
336
+| `com.ruoyi.web.modules.home` 包 | **已创建** |
337
+| `HomeAppServiceImplTest` / `HomeAppControllerTest` | **已实现**(24 用例) |
328 338
 | 可选索引 `idx_home_hot` | **待评估** |
329 339
 | C 端首页前端 | **未实现** |
330 340
 
@@ -347,7 +357,8 @@ HomeAppServiceImpl
347 357
 | 版本 | 说明 |
348 358
 |------|------|
349 359
 | **v1.0** | 首版;无新建表;`/api/home` 三读接口;关联 Banner/分类/商品/店铺方案 |
360
+| **v1.1** | 三接口 **已实现**;Banner 迁入 `home` 包(`HomeAppMapper` 直读 `biz_home_banner`);单测/接口测落地 |
350 361
 
351 362
 ---
352 363
 
353
-*文档版本:v1.0 · MySQL 5.7.39 · RuoYi v3.9.2-springboot2 · 关联《商城首页功能需求.md》v1.0.1、《首页banner设置技术方案.md》v1.0*
364
+*文档版本:v1.1 · MySQL 5.7.39 · RuoYi v3.9.2-springboot2 · 关联《商城首页功能需求.md》v1.0.1、《首页banner设置技术方案.md》v1.0.1*

+ 16 - 14
doc/消费者APP/商城首页/商城首页测试用例.md

@@ -1,8 +1,9 @@
1 1
 # 商城首页 — 测试用例
2 2
 
3
-> **依据:** 《商城首页功能需求.md》v1.0.1、《商城首页技术方案.md》v1.0  
3
+> **依据:** 《商城首页功能需求.md》v1.0.1、《商城首页技术方案.md》v1.1  
4 4
 > **关联:** 平台《首页banner设置测试用例.md》BAN-API-018~020(同源 `/api/home/banners`)、平台《商品分类测试用例.md》、《关联需求分析.md》§11  
5 5
 > **范围:** C 端商城首页;`/api/home/banners`、`/api/home/categories`、`/api/home/hot-goods`;`HomeAppServiceImpl` / `HomeAppController`  
6
+> **代码落位:** `baqing-shop/src/main/java/com/ruoyi/web/modules/home/`  
6 7
 > **排除:** 搜索执行与结果页、商品详情可购四条件校验、Banner 平台 CRUD、下拉刷新、聚合 `/api/home/index`  
7 8
 > **环境:** RuoYi v3.9.2-springboot2;MySQL 5.7.39;C 端 **无需 Token**(`@Anonymous`);UI 使用 Playwright **`channel: 'chrome'`**
8 9
 
@@ -727,24 +728,24 @@
727 728
 
728 729
 ---
729 730
 
730
-## 五、自动化映射(规划)
731
+## 五、自动化映射
731 732
 
732
-| 用例 | 建议代码位置 |
733
-|------|--------------|
734
-| MHP-UT-001~012 | `HomeAppServiceImplTest.java` |
735
-| MHP-API-001~018 | `HomeAppControllerTest.java`;Banner 部分复用 `HomeBannerAppControllerTest` |
736
-| MHP-UI-001~017 | `e2e/consumer/mall-home.spec.ts`(Playwright `channel: 'chrome'`) |
733
+| 用例 | 代码位置 | 状态 |
734
+|------|----------|------|
735
+| MHP-UT-001~012 + Banner | `HomeAppServiceImplTest.java` | **已实现**(17 用例) |
736
+| MHP-API-001~018 + Banner | `HomeAppControllerTest.java` | **已实现**(8 用例) |
737
+| MHP-UI-001~017 | `e2e/consumer/mall-home.spec.ts`(Playwright `channel: 'chrome'`) | **待实现** |
737 738
 
738 739
 ---
739 740
 
740 741
 ## 六、用例统计
741 742
 
742
-| 类型 | 数量 |
743
-|------|------|
744
-| 单元测试 MHP-UT | 12 |
745
-| 接口测试 MHP-API | 18 |
746
-| 界面测试 MHP-UI | 17 |
747
-| **合计** | **47** |
743
+| 类型 | 数量 | 自动化 |
744
+|------|------|--------|
745
+| 单元测试 MHP-UT | 12 | 17(含 Banner 3) |
746
+| 接口测试 MHP-API | 18 | 8(核心契约) |
747
+| 界面测试 MHP-UI | 17 | 待实现 |
748
+| **合计** | **47** | **25 已实现** |
748 749
 
749 750
 ---
750 751
 
@@ -753,7 +754,8 @@
753 754
 | 版本 | 说明 |
754 755
 |------|------|
755 756
 | **v1.0** | 首版;47 用例;覆盖 HM1~HM15、BN C 端协作、v1.0.1 排序/空态/不做下拉刷新 |
757
+| **v1.1** | 同步技术方案 v1.1;§5 自动化映射标注 **已实现**;Banner 测试归 `HomeApp*Test` |
756 758
 
757 759
 ---
758 760
 
759
-*文档版本:v1.0 · 关联《商城首页功能需求.md》v1.0.1、《商城首页技术方案.md》v1.0*
761
+*文档版本:v1.1 · 关联《商城首页功能需求.md》v1.0.1、《商城首页技术方案.md》v1.1*