120 lines
3.2 KiB
Vue
120 lines
3.2 KiB
Vue
<template>
|
||
<view class="page-container">
|
||
<view class="header-actions">
|
||
<button type="primary" size="mini" @click="openArticleDrawer()">
|
||
添加文章
|
||
</button>
|
||
<button
|
||
type="default"
|
||
size="mini"
|
||
@click="openCategoryDrawer()"
|
||
style="margin-left: 10px"
|
||
>
|
||
分类管理
|
||
</button>
|
||
</view>
|
||
|
||
<uni-table border stripe emptyText="暂无数据">
|
||
<uni-tr>
|
||
<uni-th width="50" align="center">ID</uni-th>
|
||
<uni-th align="center">文章标题</uni-th>
|
||
<uni-th width="150" align="center">文章分类</uni-th>
|
||
<uni-th width="200" align="center">摘要</uni-th>
|
||
<uni-th width="150" align="center">操作</uni-th>
|
||
</uni-tr>
|
||
<uni-tr v-for="item in articleList" :key="item.id">
|
||
<uni-td align="center">{{ item.id }}</uni-td>
|
||
<uni-td align="center">{{ item.title }}</uni-td>
|
||
<uni-td align="center">{{ getCategoryName(item.categoryId) }}</uni-td>
|
||
<uni-td align="center">{{ item.summary }}</uni-td>
|
||
<uni-td align="center">
|
||
<button size="mini" type="primary" @click="openArticleDrawer(item)">
|
||
编辑
|
||
</button>
|
||
</uni-td>
|
||
</uni-tr>
|
||
</uni-table>
|
||
|
||
<view class="pagination-box">
|
||
<uni-pagination
|
||
:total="total"
|
||
:current="page"
|
||
:pageSize="pageSize"
|
||
@change="onPageChange"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 抽屉组件 -->
|
||
<ArticleFormDrawer ref="articleDrawerRef" @success="fetchArticles" />
|
||
<CategoryFormDrawer ref="categoryDrawerRef" @success="fetchCategories" />
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted } from "vue";
|
||
import { api } from "@/services/api.js";
|
||
import mockStore from "@/stores/useMockData.js";
|
||
import ArticleFormDrawer from "@/components/ArticleFormDrawer.vue";
|
||
import CategoryFormDrawer from "@/components/CategoryFormDrawer.vue";
|
||
|
||
const articleList = ref([]);
|
||
const total = ref(0);
|
||
const page = ref(1);
|
||
const pageSize = ref(10);
|
||
|
||
const articleDrawerRef = ref(null);
|
||
const categoryDrawerRef = ref(null);
|
||
|
||
const fetchArticles = async () => {
|
||
const res = await api.getArticles(page.value, pageSize.value);
|
||
if (res.code === 200) {
|
||
articleList.value = res.data.list;
|
||
total.value = res.data.total;
|
||
}
|
||
};
|
||
|
||
const fetchCategories = async () => {
|
||
// 触发分类数据更新,由于使用了 reactive,这里其实可以不调接口,但为了模拟真实流程还是调用一下
|
||
await api.getCategories();
|
||
};
|
||
|
||
const getCategoryName = (categoryId) => {
|
||
const category = mockStore.mockCategories.find((c) => c.id === categoryId);
|
||
return category ? category.name : "未知分类";
|
||
};
|
||
|
||
const onPageChange = (e) => {
|
||
page.value = e.current;
|
||
fetchArticles();
|
||
};
|
||
|
||
const openArticleDrawer = (row = null) => {
|
||
articleDrawerRef.value.open(row);
|
||
};
|
||
|
||
const openCategoryDrawer = (row = null) => {
|
||
categoryDrawerRef.value.open(row);
|
||
};
|
||
|
||
onMounted(() => {
|
||
fetchCategories();
|
||
fetchArticles();
|
||
});
|
||
</script>
|
||
|
||
<style scoped>
|
||
.page-container {
|
||
padding: 20px;
|
||
background-color: #fff;
|
||
}
|
||
.header-actions {
|
||
margin-bottom: 20px;
|
||
display: flex;
|
||
}
|
||
.pagination-box {
|
||
margin-top: 20px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
}
|
||
</style>
|