參看樂優商城(三)商品分類管理
https://blog.csdn.net/lyj2018gyq/article/details/82220560
4.實現商品分類查詢
商城的核心自然是商品,而商品多了以後,肯定要進行分類,並且不同的商品會有不同的品牌信息,我們需要依次去完成:商品分類、品牌、商品的開發。
4.1.導入數據
首先導入課前資料提供的sql:
我們先看商品分類表:
CREATE TABLE `tb_category` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '類目id',
`name` varchar(20) NOT NULL COMMENT '類目名稱',
`parent_id` bigint(20) NOT NULL COMMENT '父類目id,頂級類目填0',
`is_parent` tinyint(1) NOT NULL COMMENT '是否爲父節點,0爲否,1爲是',
`sort` int(4) NOT NULL COMMENT '排序指數,越小越靠前',
PRIMARY KEY (`id`),
KEY `key_parent_id` (`parent_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1424 DEFAULT CHARSET=utf8 COMMENT='商品類目表,類目和商品(spu)是一對多關係,類目與品牌是多對多關係';
因爲商品分類會有層級關係,因此這裏我們加入了parent_id
字段,對本表中的其它分類進行自關聯。
4.2.實現功能
在瀏覽器頁面點擊“分類管理”菜單:
根據這個路由路徑到路由文件(src/route/index.js),可以定位到分類管理頁面:
由路由文件知,頁面是src/pages/item/Category.vue
商品分類使用了樹狀結構,而這種結構的組件vuetify並沒有爲我們提供,這裏自定義了一個樹狀組件。不要求實現或者查詢組件的實現,只要求可以參照文檔使用該組件即可:
4.2.1.url異步請求
點擊商品管理下的分類管理子菜單,在瀏覽器控制檯可以看到:
頁面中沒有,只是發起了一條請求:http://api.leyou.com/api/item/category/list?pid=0
大家可能會覺得很奇怪,我們明明是使用的相對路徑:/item/category/list,講道理髮起的請求地址應該是:
http://manage.leyou.com/item/category/list
但實際卻是:
http://api.leyou.com/api/item/category/list?pid=0
這是因爲,我們有一個全局的配置文件,對所有的請求路徑進行了約定:
路徑是http://api.leyou.com,並且默認加上了/api的前綴,這恰好與我們的網關設置匹配,我們只需要把地址改成網關的地址即可,因爲我們使用了nginx反向代理,這裏可以寫域名。
接下來,我們要做的事情就是編寫後臺接口,返回對應的數據即可。
4.2.2.實體類
在leyou-item-interface
中添加category實體類:
內容:
@Table(name="tb_category")
public class Category {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String name;
private Long parentId;
private Boolean isParent; // 注意isParent生成的getter和setter方法需要手動加上Is
private Integer sort;
// getter和setter略
}
需要注意的是,這裏要用到jpa的註解,因此我們在leyou-item-iterface
中添加jpa依賴
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
4.2.3.controller
編寫一個controller一般需要知道四個內容:
- 請求方式:決定我們用GetMapping還是PostMapping
- 請求路徑:決定映射路徑
- 請求參數:決定方法的參數
- 返回值結果:決定方法的返回值
在剛纔頁面發起的請求中,我們就能得到絕大多數信息:
-
請求方式:Get,插敘肯定是get請求
-
請求路徑:/api/item/category/list。其中/api是網關前綴,/item是網關的路由映射,真實的路徑應該是/category/list
-
請求參數:pid=0,根據tree組件的說明,應該是父節點的id,第一次查詢爲0,那就是查詢一級類目
-
返回結果:??
根據前面tree組件的用法我們知道,返回的應該是json數組:
[ { "id": 74, "name": "手機", "parentId": 0, "isParent": true, "sort": 2 }, { "id": 75, "name": "家用電器", "parentId": 0, "isParent": true, "sort": 3 } ]
對應的java類型可以是List集合,裏面的元素就是類目對象了。也就是
List<Category>
添加Controller:
controller代碼:
@Controller
@RequestMapping("category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 根據父id查詢子節點
* @param pid
* @return
*/
@GetMapping("list")
public ResponseEntity<List<Category>> queryCategoriesByPid(@RequestParam("pid") Long pid) {
if (pid == null || pid.longValue() < 0) {
// 響應400,相當於ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
return ResponseEntity.badRequest().build();
}
List<Category> categories = this.categoryService.queryCategoriesByPid(pid);
if (CollectionUtils.isEmpty(categories)) {
// 響應404
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(categories);
}
}
4.2.4.service
一般service層我們會定義接口和實現類,不過這裏我們就偷懶一下,直接寫實現類了:
@Service
public class CategoryService {
@Autowired
private CategoryMapper categoryMapper;
/**
* 根據parentId查詢子類目
* @param pid
* @return
*/
public List<Category> queryCategoriesByPid(Long pid) {
Category record = new Category();
record.setParentId(pid);
return this.categoryMapper.select(record);
}
}
4.2.5.mapper
我們使用通用mapper來簡化開發:
public interface CategoryMapper extends Mapper<Category> {
}
要注意,我們並沒有在mapper接口上聲明@Mapper註解,那麼mybatis如何才能找到接口呢?
我們在啓動類上添加一個掃描包功能:
@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.leyou.item.mapper") // mapper接口的包掃描
public class LeyouItemServiceApplication {
public static void main(String[] args) {
SpringApplication.run(LeyouItemServiceApplication.class, args);
}
}
4.2.6.啓動並測試
我們不經過網關,直接訪問:http://localhost:8081/category/list
然後試試網關是否暢通:http://api.leyou.com/api/item/category/list
一切OK!
然後刷新後臺管理頁面查看:
發現報錯了!
瀏覽器直接訪問沒事,但是這裏卻報錯,什麼原因?
這其實是瀏覽器的同源策略造成的跨域問題。
5.跨域問題
參看