乐优商城之后台管理系统
文章目錄
- 商品分類管理
- 實現(xiàn)功能
- 實體類
- controller
- service
- mapper
- 跨域問題(cors)
- 品牌查詢
- controller
- PageResult
- Service
- 異步查詢工具axios
- axios的全局配置
- 項目中使用
- 完成分頁和過濾
- 品牌管理
- 商品規(guī)格管理
- 商品管理
商品分類管理
商城的核心自然是商品,而商品多了以后,肯定要進行分類,并且不同的商品會有不同的品牌信息,我們需要依次去完成:商品分類、品牌、商品的開發(fā)。
- 導入數(shù)據(jù)(sql)
實現(xiàn)功能
商品分類使用了樹狀結(jié)構(gòu),而這種結(jié)構(gòu)的組件vuetify并沒有為我們提供,這里自定義了一個樹狀組件。不要求實現(xiàn)或者查詢組件的實現(xiàn),只要求可以參照文檔使用該組件即可:
在瀏覽器頁面點擊“分類管理”菜單:
根據(jù)這個路由路徑到路由文件(src/route/index.js),可以定位到分類管理頁面:
由路由文件知,頁面是src/pages/item/Category.vue
實體類
在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方法需要手動加上Isprivate Integer sort;// getter和setter略 }controller
編寫一個controller一般需要知道四個內(nèi)容:
- 請求方式:決定我們用GetMapping還是PostMapping - 請求路徑:決定映射路徑 - 請求參數(shù):決定方法的參數(shù) - 返回值結(jié)果:決定方法的返回值在剛才頁面發(fā)起的請求中,我們就能得到絕大多數(shù)信息:
- 請求方式:Get,插敘肯定是get請求
- 請求路徑:/api/item/category/list。其中/api是網(wǎng)關(guān)前綴,/item是網(wǎng)關(guān)的路由映射,真實的路徑應(yīng)該是/category/list
- 請求參數(shù):pid=0,根據(jù)tree組件的說明,應(yīng)該是父節(jié)點的id,第一次查詢?yōu)?,那就是查詢一級類目
- 返回結(jié)果:??
根據(jù)前面tree組件的用法我們知道,返回的應(yīng)該是json數(shù)組:對應(yīng)的java類型可以是List集合,里面的元素就是類目對象了。也就是List
ResponseEntity
service
一般service層我們會定義接口和實現(xiàn)類,不過這里我們就偷懶一下,直接寫實現(xiàn)類了:
@Service public class CategoryService {@Autowiredprivate CategoryMapper categoryMapper;/*** 根據(jù)parentId查詢子類目* @param pid* @return*/public List<Category> queryCategoriesByPid(Long pid) {Category record = new Category();record.setParentId(pid);return this.categoryMapper.select(record);} }mapper
我們使用通用mapper來簡化開發(fā):
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);} }跨域問題(cors)
跨域問題(cors)](https://blog.csdn.net/chenhangx/article/details/105413599)
品牌查詢
路由路徑:/item/brand
根據(jù)路由文件知,對應(yīng)的頁面是:src/pages/item/Brand.vue
`tb_brand`ENGINE=InnoDB AUTO_INCREMENT=325400 DEFAULT CHARSET=utf8 COMMENT='品牌表,一個品牌下有多個商品(spu),一對多關(guān)系';這里需要注意的是,品牌和商品分類之間是多對多關(guān)系。因此我們有一張中間表,來維護兩者間關(guān)系:
CREATE TABLE `tb_category_brand` (`category_id` bigint(20) NOT NULL COMMENT '商品類目id',`brand_id` bigint(20) NOT NULL COMMENT '品牌id',PRIMARY KEY (`category_id`,`brand_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品分類和品牌的中間表,兩者是多對多關(guān)系';但是,你可能會發(fā)現(xiàn),這張表中并沒有設(shè)置外鍵約束,似乎與數(shù)據(jù)庫的設(shè)計范式不符。為什么這么做?
- 外鍵會嚴重影響數(shù)據(jù)庫讀寫的效率
- 數(shù)據(jù)刪除時會比較麻煩
在電商行業(yè),性能是非常重要的。我們寧可在代碼中通過邏輯來維護表關(guān)系,也不設(shè)置外鍵。
controller
編寫controller先思考四個問題,參照前端頁面的控制臺
- 請求方式:查詢,肯定是Get
- 請求路徑:分頁查詢,/brand/page
- 請求參數(shù):根據(jù)我們剛才編寫的頁面,有分頁功能,有排序功能,有搜索過濾功能,因此至少要有5個參數(shù):
- page:當前頁,int
- rows:每頁大小,int
- sortBy:排序字段,String
- desc:是否為降序,boolean
- key:搜索關(guān)鍵詞,String
- 響應(yīng)結(jié)果:分頁結(jié)果一般至少需要兩個數(shù)據(jù)
- total:總條數(shù)
- items:當前頁數(shù)據(jù)
- totalPage:有些還需要總頁數(shù)
PageResult
這里我們封裝一個類,來表示分頁結(jié)果:
public class PageResult<T> {private Long total;// 總條數(shù)private Integer totalPage;// 總頁數(shù)private List<T> items;// 當前頁數(shù)據(jù)public PageResult() {}public PageResult(Long total, List<T> items) {this.total = total;this.items = items;}public PageResult(Long total, Long totalPage, List<T> items) {this.total = total;this.totalPage = totalPage;this.items = items;}public Long getTotal() {return total;}public void setTotal(Long total) {this.total = total;}public List<T> getItems() {return items;}public void setItems(List<T> items) {this.items = items;}public Long getTotalPage() {return totalPage;}public void setTotalPage(Long totalPage) {this.totalPage = totalPage;} }另外,這個PageResult以后可能在其它項目中也有需求,因此我們將其抽取到leyou-common中,提高復(fù)用性:
不要忘記在leyou-item-service工程的pom.xml中引入leyou-common的依賴:
Service
@Service public class BrandService {@Autowiredprivate BrandMapper brandMapper;/*** 根據(jù)查詢條件分頁并排序查詢品牌信息** @param key* @param page* @param rows* @param sortBy* @param desc* @return*/public PageResult<Brand> queryBrandsByPage(String key, Integer page, Integer rows, String sortBy, Boolean desc) {// 初始化example對象Example example = new Example(Brand.class);Example.Criteria criteria = example.createCriteria();// 根據(jù)name模糊查詢,或者根據(jù)首字母查詢if (StringUtils.isNotBlank(key)) {criteria.andLike("name", "%" + key + "%").orEqualTo("letter", key);}// 添加分頁條件PageHelper.startPage(page, rows);// 添加排序條件if (StringUtils.isNotBlank(sortBy)) {example.setOrderByClause(sortBy + " " + (desc ? "desc" : "asc"));}List<Brand> brands = this.brandMapper.selectByExample(example);// 包裝成pageInfoPageInfo<Brand> pageInfo = new PageInfo<>(brands);// 包裝成分頁結(jié)果集返回return new PageResult<>(pageInfo.getTotal(), pageInfo.getList());} }異步查詢工具axios
異步查詢數(shù)據(jù),自然是通過ajax查詢,大家首先想起的肯定是jQuery。但jQuery與MVVM的思想不吻合,而且ajax只是jQuery的一小部分。因此不可能為了發(fā)起ajax請求而去引用這么大的一個庫。
Vue官方推薦的ajax請求框架叫做:axios
axios的Get請求語法:
axios的POST請求語法:
比如新增一個用戶
axios.post("/user",{name:"Jack",age:21}).then(function(resp){}).catch(function(error){})注意,POST請求傳參,不需要像GET請求那樣定義一個對象,在對象的params參數(shù)中傳參。post()方法的第二個參數(shù)對象,就是將來要傳遞的參數(shù)
PUT和DELETE請求與POST請求類似
axios的全局配置
而在我們的項目中,已經(jīng)引入了axios,并且進行了簡單的封裝,在src下的http.js中:
http.js中對axios進行了一些默認配置:
項目中使用
我們在組件Brand.vue的getDataFromServer方法,通過$http發(fā)起get請求,測試查詢品牌的接口,看是否能獲取到數(shù)據(jù):
可以看到,在請求成功的返回結(jié)果response中,有一個data屬性,里面就是真正的響應(yīng)數(shù)據(jù)。
響應(yīng)結(jié)果中與我們設(shè)計的一致,包含3個內(nèi)容:
- total:總條數(shù),目前是165
- items:當前頁數(shù)據(jù)
- totalPage:總頁數(shù),我們沒有返回
完成分頁和過濾
品牌管理
商品規(guī)格管理
商品管理
總結(jié)
以上是生活随笔為你收集整理的乐优商城之后台管理系统的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SPSS是什么?
- 下一篇: luogu1091合唱队形