一、課程分類添加前端實現
1、配置路由
在src/router/index.js
中添加路由
//課程分類路由
{
path: '/subject',
component: Layout,
redirect: '/subject/list',
name: '課程分類管理',
meta: { title: '課程分類管理', icon: 'example' },
children: [
{
path: 'list',
name: '課程分類列表',
component: () => import('@/views/edu/subject/list'),
meta: { title: '課程分類', icon: 'table' }
},
{
path: 'save',
name: '添加課程分類',
component: () => import('@/views/edu/subject/save'),
meta: { title: '添加課程分類', icon: 'tree' }
},
]
},
2、添加vue組件
在scr/view
中創建subject文件夾,並加入list.vue
和save.vue
兩個vue文件
3、實現save.vue
1)編寫html組件
<template>
<div class="app-container">
<el-form label-width="120px">
<el-form-item label="信息描述">
<el-tag type="info">excel模版說明</el-tag>
<el-tag>
<i class="el-icon-download"/>
<a :href="'/static/template.xlsx'">點擊下載模版</a>
</el-tag>
</el-form-item>
<el-form-item label="選擇Excel">
<el-upload
ref="upload"
:auto-upload="false"
:on-success="fileUploadSuccess"
:on-error="fileUploadError"
:disabled="importBtnDisabled"
:limit="1"
:action="BASE_API+'/eduservice/subject/addSubject'"
name="file"
accept="application/vnd.ms-excel">
<el-button slot="trigger" size="small" type="primary">選取文件</el-button>
<el-button
:loading="loading"
style="margin-left: 10px;"
size="small"
type="success"
@click="submitUpload">上傳到服務器</el-button>
</el-upload>
</el-form-item>
</el-form>
</div>
</template>
2)編寫js腳本
<script>
export default {
data(){
return{
BASE_API: process.env.BASE_API, // 接口API地址
importBtnDisabled: false, // 按鈕是否禁用,
loading: false
}
},
created(){
},
methods:{
//點擊按鈕上傳文件到接口
submitUpload(){
this.importBtnDisabled = true
this.loading = true
//提交表單
//js寫法:document.getElementById("upload").submit();
this.$refs.upload.submit()
},
//上傳成功的事件
fileUploadSuccess(){
this.loading = false
this.$message({
type: 'success',
message: '添加課程分類成功'
})
//跳轉到課程分類的列表界面
this.$router.push({path : "/subject/list"})
},
//上傳失敗的事件
fileUploadError(){
this.loading = false
this.$message({
type: 'error',
message: '添加課程分類失敗'
})
}
}
}
</script>
4、測試
進入課程分類添加路由
點擊 選取文件 按鈕,選擇含有課程分類的信息的excel文件
點擊 上傳到服務器按鈕 等待上傳成功。上傳成功之後,會有成功提示,而且會跳轉到課程分類頁面。
數據庫中也添加了相應的信息
二、實現課程分類列表顯示
1、添加前端頁面
在src/view/subject/list.vue
中添加下面的模版本內容:
<template>
<div class="app-container">
<el-input v-model="filterText" placeholder="關鍵字" style="margin-bottom:30px;" />
<el-tree
ref="tree2"
:data="data2"
:props="defaultProps"
:filter-node-method="filterNode"
class="filter-tree"
default-expand-all
/>
</div>
</template>
<script>
export default {
data() {
return {
filterText: '',
data2: [{
id: 1,
label: 'Level one 1',
children: [{
id: 4,
label: 'Level two 1-1',
children: [{
id: 9,
label: 'Level three 1-1-1'
}, {
id: 10,
label: 'Level three 1-1-2'
}]
}]
}, {
id: 2,
label: 'Level one 2',
children: [{
id: 5,
label: 'Level two 2-1'
}, {
id: 6,
label: 'Level two 2-2'
}]
}, {
id: 3,
label: 'Level one 3',
children: [{
id: 7,
label: 'Level two 3-1'
}, {
id: 8,
label: 'Level two 3-2'
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
watch: {
filterText(val) {
this.$refs.tree2.filter(val)
}
},
methods: {
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
}
}
}
</script>
顯示效果:
其中樹狀圖中的數據都定義在data的data2中,這個就是後臺需要返回的數據。而且數據格式要和data2定義的一致,組件才能識別。
2、後端定義樹狀數據類型
package cn.hanzhuang42.eduservice.entity.subject;
import lombok.Data;
import java.util.List;
/**
* 用於封裝返回的樹狀數據
*/
@Data
public class SubjectResult {
//id
private String id;
//名稱
private String title;
//如果是一級分類用於存放其子分類
//如果是二級分類則爲空
private List<SubjectResult> children = null;
}
3、後端定義Controller接口
/**
* 獲取課程分類信息,並一樹狀結構返回
* @return
*/
@GetMapping("getAll")
public R getAllSubject(){
List<SubjectResult> res = subjectService.getAllSubject();
return R.ok().data("data", res);
}
4、後端service添加封裝結果集方法
在接口EduSubjectService中添加方法
public interface EduSubjectService extends IService<EduSubject> {
...//其他方法定義
List<SubjectResult> getAllSubject();
}
在service實現類EduSubjectServiceImpl中添加對應的實現方法。
主要功能就是將數據庫中的課程分類信息封裝成上邊前端中data2那樣的格式,詳細過程參見代碼
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements EduSubjectService {
...//其他方法實現
@Override
public List<SubjectResult> getAllSubject() {
List<EduSubject> rowData = this.list();
List<SubjectResult> res = new ArrayList<>();
//用於存儲 SubjectResult 的 id 和在 List 中索引的對應關係,便於之後存取
Map<String, Integer> map = new HashMap<>();
int i = 0;
//先將一級分類存儲到 res 中
for (EduSubject subject : rowData) {
if ("0".equals(subject.getParentId())){
//通過 EduSubject 創建一個 一級分類SubjectResult
SubjectResult subjectResult = new SubjectResult();
String topId = subject.getId();
subjectResult.setId(topId);
subjectResult.setTitle(subject.getTitle());
subjectResult.setChildren(new ArrayList<>());
//將一級分類 SubjectResult 放入list中
res.add(subjectResult);
map.put(topId, i++);
}
}
//將二級分類存儲到對應的一級分類中
for (EduSubject subject : rowData) {
String parentId = subject.getParentId();
if (!"0".equals(parentId)) {
//通過 EduSubject 創建一個 二級分類SubjectResult
SubjectResult subjectResult = new SubjectResult();
subjectResult.setId(subject.getId());
subjectResult.setTitle(subject.getTitle());
//通過 parentId 先獲取 list 中的索引,再通過索引獲得 parent
SubjectResult parent = res.get(map.get(parentId));
//將二級分類加入到對應的一級分類中
parent.getChildren().add(subjectResult);
}
}
return res;
}
}
5、添加前端api接口
在前端中的src/api/edu
中添加subject.js
接口定義
import request from '@/utils/request'
export default {
/**
* 獲得課程分類信息(樹狀)
*/
getAllSubject(){
return request({
url: `/eduservice/subject/getAll`,
method: 'get'
})
},
}
6、修改前端頁面的中js內容
在前端頁面中通過js調用後端接口獲取數據
<script>
import subjectApi from '@/api/edu/subject.js'
export default {
data() {
return {
filterText: '',
data2: [], //返回所有分類的數據(樹狀)
defaultProps: {
children: 'children',
label: 'title'
}
}
},
watch: {
filterText(val) {
this.$refs.tree2.filter(val)
}
},
created(){
this.getAllSubject()
},
methods: {
getAllSubject(){
subjectApi.getAllSubject()
.then(response =>{
this.data2 = response.data.list
})
},
filterNode(value, data) {
if (!value) return true
//比較時都用小寫
return data.title.toLowerCase().indexOf(value.toLowerCase()) !== -1
}
}
}
</script>
7、測試
重啓服務,進入頁面點擊導航上的課程分類,內容顯示沒有問題
在搜索框中輸入關鍵字。可以進行過濾,而且不區分大小寫