补充删除接口
This commit is contained in:
parent
0cb097f5ec
commit
d578bdcba2
@ -50,6 +50,7 @@ func (h *BlogApiHandler) Init() error {
|
|||||||
|
|
||||||
r.Use(middleware.Auth)
|
r.Use(middleware.Auth)
|
||||||
r.POST("", h.CreateBlog)
|
r.POST("", h.CreateBlog)
|
||||||
|
r.DELETE(":id", h.DeleteBlog)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,3 +91,14 @@ func (h *BlogApiHandler) QueryBlog(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
response.Success(ctx, ins)
|
response.Success(ctx, ins)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *BlogApiHandler) DeleteBlog(ctx *gin.Context) {
|
||||||
|
in := blog.NewDeleteBlogRequest(ctx.Param("id"))
|
||||||
|
|
||||||
|
err := h.blog.DeleteBlog(ctx.Request.Context(), in)
|
||||||
|
if err != nil {
|
||||||
|
response.Failed(ctx, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Success(ctx, "ok")
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ package blog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/infraboard/mcube/v2/ioc"
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
@ -31,6 +32,23 @@ type Service interface {
|
|||||||
DeleteBlog(context.Context, *DeleteBlogRequest) error
|
DeleteBlog(context.Context, *DeleteBlogRequest) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewDeleteBlogRequest[T int | string](id T) *DeleteBlogRequest {
|
||||||
|
var idValue int
|
||||||
|
switch v := any(id).(type) {
|
||||||
|
case int:
|
||||||
|
idValue = v
|
||||||
|
case string:
|
||||||
|
parsedID, _ := strconv.ParseUint(v, 10, 0)
|
||||||
|
idValue = int(parsedID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DeleteBlogRequest{
|
||||||
|
GetRequest: utils.GetRequest{
|
||||||
|
Id: uint(idValue),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type DeleteBlogRequest struct {
|
type DeleteBlogRequest struct {
|
||||||
utils.GetRequest
|
utils.GetRequest
|
||||||
}
|
}
|
||||||
|
@ -407,3 +407,40 @@ css, :deep(), 用于选择需要覆盖的class进行覆盖
|
|||||||
padding-left: 0px;
|
padding-left: 0px;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 列表页
|
||||||
|
|
||||||
|
- 页头/过滤条件/表格展示
|
||||||
|
|
||||||
|
后端分页, 默认的Table使用的前端分页
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="pagination">
|
||||||
|
<a-pagination
|
||||||
|
:current="blogQueryRequest.page_number"
|
||||||
|
:page-size="blogQueryRequest.page_size"
|
||||||
|
:page-size-options="[2, 10, 20, 30, 50]"
|
||||||
|
@change="pageNumberChanged"
|
||||||
|
@page-size-change="pageSizeChanged"
|
||||||
|
:total="data.total"
|
||||||
|
show-total
|
||||||
|
show-jumper
|
||||||
|
show-page-size
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
// 实现分页
|
||||||
|
const pageNumberChanged = (current) => {
|
||||||
|
blogQueryRequest.page_number = current
|
||||||
|
// 基于新的变化重新请求数据
|
||||||
|
queryData()
|
||||||
|
}
|
||||||
|
const pageSizeChanged = (pageSize) => {
|
||||||
|
blogQueryRequest.page_size = pageSize
|
||||||
|
blogQueryRequest.page_number = 1
|
||||||
|
// 基于新的变化重新请求数据
|
||||||
|
queryData()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
</a-layout-header>
|
</a-layout-header>
|
||||||
<a-layout class="body">
|
<a-layout class="body">
|
||||||
<!-- 侧边栏 -->
|
<!-- 侧边栏 -->
|
||||||
<a-layout-sider :width="260">
|
<a-layout-sider :width="260" collapsible breakpoint="xl">
|
||||||
<a-menu @menu-item-click="handleMenuItemClick">
|
<a-menu @menu-item-click="handleMenuItemClick" breakpoint="xl">
|
||||||
<a-sub-menu key="blog">
|
<a-sub-menu key="blog">
|
||||||
<template #title>
|
<template #title>
|
||||||
<span>
|
<span>
|
||||||
@ -50,6 +50,7 @@
|
|||||||
import { token } from '@/stores/token';
|
import { token } from '@/stores/token';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const handleMenuItemClick = (key) => {
|
const handleMenuItemClick = (key) => {
|
||||||
@ -64,6 +65,7 @@ const logout = () => {
|
|||||||
router.push({ name: 'login' })
|
router.push({ name: 'login' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
|
@ -6,36 +6,71 @@
|
|||||||
</a-page-header>
|
</a-page-header>
|
||||||
</div>
|
</div>
|
||||||
<!-- table 选项 -->
|
<!-- table 选项 -->
|
||||||
<div style="display: flex;">
|
<div class="table-filter">
|
||||||
<div>
|
<a-select style="width: 300px;" v-model="blogQueryRequest.category" placeholder="请选择文章分类"
|
||||||
<a-select style="width: 300px;" placeholder="请选择文章分类">
|
@change="() => queryData()">
|
||||||
<a-option>Golang</a-option>
|
<a-option>软件开发</a-option>
|
||||||
<a-option>Java</a-option>
|
<a-option>系统运维</a-option>
|
||||||
<a-option>Python</a-option>
|
<a-option>软件测试</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="display: flex; margin-top: 12px;">
|
||||||
|
<div>
|
||||||
|
<a-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus />
|
||||||
|
</template>
|
||||||
|
新建文章
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
<div style="margin-left: auto;">
|
<div style="margin-left: auto;">
|
||||||
<a-input-search :style="{ width: '320px' }" placeholder="请输入关键字 敲回车键进行搜索" />
|
<!-- https://eslint.vuejs.org/rules/no-deprecated-v-on-native-modifier.html -->
|
||||||
|
<a-input-search v-model="blogQueryRequest.keywords" :style="{ width: '320px' }" placeholder="请输入关键字 敲回车键进行搜索"
|
||||||
|
@search="() => queryData()" @keyup.enter="() => queryData()" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 12px;">
|
<div style="margin-top: 12px;">
|
||||||
<a-table :data="data.items" :loading="queryBlogLoadding">
|
<a-table :pagination="false" :data="data.items" :loading="queryBlogLoadding">
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<a-table-column title="编码" data-index="id"></a-table-column>
|
<a-table-column title="编码" data-index="id"></a-table-column>
|
||||||
<a-table-column title="标题" data-index="title"></a-table-column>
|
<a-table-column title="标题" data-index="title"></a-table-column>
|
||||||
<a-table-column title="分类" data-index="category"></a-table-column>
|
<a-table-column title="分类" data-index="category"></a-table-column>
|
||||||
<a-table-column title="更新时间" data-index="updated_at"></a-table-column>
|
<a-table-column title="更新时间">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<span>{{ dayjs(record.updated_at).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
<a-table-column align="center" title="操作">
|
<a-table-column align="center" title="操作">
|
||||||
<template #cell="{ record }">
|
<template #cell="{ record }">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button @click="$modal.info({ title: 'Name', content: record.id })">view</a-button>
|
<a-button type="primary" @click="$modal.info({ title: 'Name', content: record.id })">
|
||||||
<a-button @click="$modal.info({ title: 'Name', content: record.id })">view</a-button>
|
<template #icon>
|
||||||
<a-button @click="$modal.info({ title: 'Name', content: record.id })">view</a-button>
|
<icon-edit />
|
||||||
|
</template>
|
||||||
|
编辑
|
||||||
|
</a-button>
|
||||||
|
<a-button type="primary" @click="$modal.info({ title: 'Name', content: record.id })">
|
||||||
|
<template #icon>
|
||||||
|
<icon-send />
|
||||||
|
</template>
|
||||||
|
发布
|
||||||
|
</a-button>
|
||||||
|
<a-button status="danger" @click="$modal.info({ title: 'Name', content: record.id })">
|
||||||
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
|
删除
|
||||||
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
|
<div class="pagination">
|
||||||
|
<a-pagination :current="blogQueryRequest.page_number" :page-size="blogQueryRequest.page_size"
|
||||||
|
:page-size-options="[2, 10, 20, 30, 50]" @change="pageNumberChanged" @page-size-change="pageSizeChanged"
|
||||||
|
:total="data.total" show-total show-jumper show-page-size />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -44,34 +79,64 @@
|
|||||||
|
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { QUERY_BLOG } from '@/api/blog'
|
import { QUERY_BLOG } from '@/api/blog'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
|
||||||
// API 请求数据
|
// API 请求数据
|
||||||
const blogQueryRequest = reactive({
|
const blogQueryRequest = reactive({
|
||||||
keywords: '',
|
keywords: '',
|
||||||
category: ''
|
category: '',
|
||||||
|
page_size: 10,
|
||||||
|
page_number: 1,
|
||||||
})
|
})
|
||||||
// 数据, reactive, 一个一个修改每个属性的值 ({data...})
|
// 数据, reactive, 一个一个修改每个属性的值 ({data...})
|
||||||
// ref data.value = {}
|
// ref data.value = {}
|
||||||
const data = ref({})
|
const data = ref({})
|
||||||
|
|
||||||
|
|
||||||
// 什么时候调用这个API, 加载数据, 界面准备好了后,再把数据渲染上去
|
|
||||||
const queryBlogLoadding = ref(false)
|
const queryBlogLoadding = ref(false)
|
||||||
onMounted(async () => {
|
const queryData = async () => {
|
||||||
try {
|
try {
|
||||||
queryBlogLoadding.value = true
|
queryBlogLoadding.value = true
|
||||||
data.value = await QUERY_BLOG(blogQueryRequest)
|
data.value = await QUERY_BLOG(blogQueryRequest)
|
||||||
} finally {
|
} finally {
|
||||||
queryBlogLoadding.value = false
|
queryBlogLoadding.value = false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 什么时候调用这个API, 加载数据, 界面准备好了后,再把数据渲染上去
|
||||||
|
onMounted(() => {
|
||||||
|
queryData()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 实现分页
|
||||||
|
const pageNumberChanged = (current) => {
|
||||||
|
blogQueryRequest.page_number = current
|
||||||
|
// 基于新的变化重新请求数据
|
||||||
|
queryData()
|
||||||
|
}
|
||||||
|
const pageSizeChanged = (pageSize) => {
|
||||||
|
blogQueryRequest.page_size = pageSize
|
||||||
|
blogQueryRequest.page_number = 1
|
||||||
|
// 基于新的变化重新请求数据
|
||||||
|
queryData()
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
|
.table-filter {
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: 2px 2px 0px 0px;
|
||||||
|
height: 120px;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.arco-page-header-wrapper) {
|
:deep(.arco-page-header-wrapper) {
|
||||||
padding-left: 0px;
|
padding-left: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user