admin-ebook.vue
使用了antd的cascader组件
<template>
<a-layout>
<a-layout-content
:style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }"
>
<p>
<a-form :model="param" layout="inline">
<a-form-item>
<a-input v-model:value="param.name" placeholder="请输入名称"></a-input>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="handleQuery({page:1,size:pagination.pageSize})">查询</a-button>
</a-form-item>
<a-form-item>
<a-button type="primary" @click="add">新增</a-button>
</a-form-item>
</a-form>
</p>
<a-table :columns="columns"
:dataSource="ebooks"
:row-key="record=>record.id"
:pagination="pagination"
:loading="loading"
@change="handleTableChange">
<template #cover="{text:cover}">
<img v-if="cover" :src="cover" alt="avatar">
</template>
<template #category="{text,record}">
<text>{{getCategoryName(record.category1Id)}}/{{getCategoryName(record.category2Id)}}</text>
</template>
<template #action="{text,record}">
<a-space>
<a-button type="primary" @click="edit(record)">编辑</a-button>
<a-popconfirm
title="删除后不可恢复,确认删除?"
ok-text="确定"
cancel-text="取消"
@confirm="handleDelete(record)"
>
<a-button type="danger">删除</a-button>
</a-popconfirm>
</a-space>
</template>
</a-table>
</a-layout-content>
</a-layout>
<a-modal
title="电子书表单"
v-model:visible="visible"
:confirm-loading="confirmLoading"
@ok="handleOk"
>
<a-form :model="ebook" :label-col="{span:4}" :wrapper-col="{span:16}">
<a-form-item label="封面">
<a-input v-model:value="ebook.cover" />
</a-form-item>
<a-form-item label="名称">
<a-input v-model:value="ebook.name" />
</a-form-item>
<!-- <a-form-item label="分类一">-->
<!-- <a-input v-model:value="ebook.category1Id" />-->
<!-- </a-form-item>-->
<!-- <a-form-item label="分类二">-->
<!-- <a-input v-model:value="ebook.category2Id" />-->
<!-- </a-form-item>-->
<a-form-item label="选择分类">
<a-cascader v-model:value="categoryIds" :options="options" @change="handleCascaderChange"
:field-names="{label:'name',value:'id',children:'children'}"/>
</a-form-item>
<a-form-item label="描述">
<a-input v-model:value="ebook.description" />
</a-form-item>
</a-form>
</a-modal>
</template>
<script lang="ts">
import {defineComponent, ref, onMounted, reactive} from 'vue';
import axios from "axios";
import {message} from "ant-design-vue";
import {arrayToTree} from "@/tools/tool";
// interface Option{
// value:String,
// label:String,
// children?:Option[]
// }
export default defineComponent({
name:"AdminEbook",
setup: function () {
const ebooks = ref();
const pagination = ref({
current: 1,
pageSize: 4,
total: 0
});
const loading = ref(false);
const columns = [
{
title: "封面",
dataIndex: "cover",
key: "cover",
slots: {customRender: 'cover'}
},
{
title: "名称",
key: "name",
dataIndex: "name"
},
// {
// title: "分类一",
// key: "category1Id",
// dataIndex: "category1Id"
// },
// {
// title: "分类二",
// key: "category2Id",
// dataIndex: "category2Id"
// },
{
title: "分类",
key: "categoryId",
slots:{customRender: "category"}
},
{
title: "文档数",
key: "docCount",
dataIndex: "docCount"
},
{
title: "阅读数",
key: "viewCount",
dataIndex: "viewCount"
},
{
title: "点赞数",
key: "vouteCount",
dataIndex: "voteCount"
},
{
title: "操作",
key: "action",
dataIndex: "action",
slots: {customRender: 'action'}
}
];
let categorys:any = [];
const categoryIds = ref();
const options = ref();
const handleCategoryQuery = () => {
loading.value = true;
axios.get("/category/all").then(response => {
loading.value = false;
const data = response.data;
if(data.success){
categorys = data.content;
const result = arrayToTree(data.content,0);
console.log("get options successfully,",result);
options.value = result;
}else{
console.log("get options failed");
}
})
}
const getCategoryName = (categoryId:number) => {
let name = "";
for(let i=0;i<categorys.length;i++){
let item = categorys[i]
if(Number(item.id) === Number(categoryId)){
name = item.name;
break;
}
}
return name;
}
const handleCascaderChange = (value:any) => {
// console.log("value,",value);
// console.log(value[0],value[1]);
// console.log("categoryIds.value,",categoryIds.value);
// console.log(categoryIds.value[0],categoryIds.value[1]);
}
const visible = ref(false);
const modalText = ref('test');
const confirmLoading = ref(false);
const ebook = ref();
const param = reactive({
name:""
});
const handleQuery = (params: any) => {
loading.value = true;
axios.get("/ebook/list", {params: {
page:params.page,
size:params.size,
name:param.name
}}).then(response => {
loading.value = false;
const data = response.data;
const content = data.content;
if (data.success) {
console.log(content.list);
ebooks.value = content.list;
pagination.value.total = content.total;
pagination.value.current = params.page;
} else {
message.warn(data.message);
}
})
};
const handleTableChange = (pagination: any) => {
handleQuery({
page: pagination.current,
size: pagination.pageSize
});
}
const edit = (record: any) => {
visible.value = true;
ebook.value = JSON.parse(JSON.stringify(record));
categoryIds.value = [ebook.value.category1Id,ebook.value.category2Id];
}
const add = () => {
visible.value = true;
ebook.value = {};
}
const handleDelete = (record: any) => {
axios.delete("ebook/delete/" + record.id).then(response => {
const data = response.data;
if (data.success) {
handleQuery({
page: pagination.value.current,
size: pagination.value.pageSize
})
}
})
}
const handleOk = () => {
ebook.value.category1Id = categoryIds.value[0];
ebook.value.category2Id = categoryIds.value[1];
axios.post("/ebook/save", ebook.value).then(response => {
const data = response.data;
if (data.success) {
visible.value = false;
confirmLoading.value = false;
handleQuery({
page: pagination.value.current,
size: pagination.value.pageSize
})
} else {
message.warn(data.message);
}
})
};
onMounted(() => {
handleCategoryQuery();
handleQuery({
page: 1,
size: pagination.value.pageSize
});
})
return {
columns,
ebooks,
loading,
pagination,
visible,
modalText,
confirmLoading,
ebook,
param,
categoryIds,
options,
handleTableChange,
edit,
add,
handleDelete,
handleOk,
handleQuery,
handleCascaderChange,
getCategoryName
}
}
})
</script>
<style scoped>
img{
width: 48px;
height: 48px;
}
</style>
- 将
arrayToTree
封装在tool.ts
中
//tool.ts
interface DataItem {
id:number,
name:string,
parent:number,
children?:DataItem[]
}
export const arrayToTree = (arr:DataItem[],rootId:number) => {
const res:DataItem[] = [];
const len = arr.length;
if(len === 0) return res;
for(let i=0;i<len;i++){
const item = arr[i];
if(Number(item.parent) === Number(rootId)){
res.push(item);
const children = arrayToTree(arr,item.id);
if(children.length!==0){
item.children = children;
}
}
}
return res;
}